hqt
hqt

Reputation: 30276

OOP Java : can return an child class to parent class?

I'm a newcomer of OOP, so I has one silly question about when a class extends another class.

Here my example:

public class Test {
    public Monitor getMonitor(){
        return new LCD();
    }

    class LCD extends Monitor {   NO-ERROR
    class LCD {                   ERROR at line `return new LCD` 
        //some other method or function not in Monitor Class. Example:
        boolean isSamsung;
        public LCD whatkindLCD(){           
        }       
    }
}

I have one question for above code : because LCD is extended from Monitor and LCD has some other properties/methods that Monitor does not. So, LCD is child of Monitor, right ?

It means you try to put a "big box" to a "small box". So, why when I return new LCD, Eclipse don't notice error as when I just use class LCD {.

Thanks :)

Upvotes: 0

Views: 454

Answers (4)

gpr
gpr

Reputation: 485

Your method getMonitor returns a "Monitor" type.

When you extend your class LCD with Monitor, you are saying the complier that LCD is a Monitor. When you remove the extends, the LCD class becomes a plain class and not a Monitor type. If you modify your getMonitor to

public LCD getMonitor(){
       // code here
}

The error will go.

Upvotes: 0

Andrzej Doyle
Andrzej Doyle

Reputation: 103797

In your second (error) case, you've forgotten to declare that LCD does in fact extend Monitor. You're just defining a "normal", standalone class - and so a new LCD() is not an instance of Monitor.

The compiler should be happy if you declare the LCD class like this:

class LCD extends Monitor {
    //some other method or function not in Monitor Class. Example:
    boolean isSamsung;
    public LCD whatkindLCD(){           
    }       
}

Edit (in response to comment): It's not a problem at all that the LCD class has extra properties/methods compared to Monitor. The code that's going to call getMonitor(), only really cares that it gets a Monitor back - that is, something that has all the methods and properties and behaviour of a Monitor.

So if you had turnOff and displayBitmap(int[][] data) methods on your Monitor class, then your LCD class will also have these methods. Any instance of LCD can behave as a Monitor when one is needed - this is the basic principle of subclassing in OO languages. So whenever something wants a Monitor, you can give it an LCD, or an instance of CRT or SamsungLCD instead if you had those, and the compiler can be satisfied that the right methods/properties will exist and can be called.

(Technically this is the Liskov substitution principle if you like formal definitions, but you don't need to understand it in that level of detail.)

Upvotes: 5

John Eipe
John Eipe

Reputation: 11228

Understand Inheritance as a "is a" relationship. Here is a simple example I used to understand inheritance during my novice years.

class Employee
{
    String name;
    int salary;

    Employee()
    {
        name = "Employee";
        salary = 5000;
    }
    public String getName()
    {
        return name;
    }
    public int getSalary()
    {
        return salary;
    }
}
class Manager extends Employee
{
    int bonus;
    int salary;

    Manager()
    {
        bonus = 1000;
        salary = 6000;
    }
    public int getBonus()
    {
        return bonus;
    }
    public int getSalary()
    {
        return salary;
    }   
}

class Test
{        
    public static void main(String[] args)
    {
        Employee e = new Employee();
        System.out.println(e.getName());
        //System.out.println(e.getBonus());
        System.out.println(e.getSalary());

        System.out.println();

        Manager m = new Manager();
        System.out.println(m.getName());
        System.out.println(m.getBonus());
        System.out.println(m.getSalary());

        System.out.println();

        Employee em = new Manager();
        System.out.println(em.getName());                   
        //System.out.println(em.getBonus());            
        System.out.println(((Manager)em).getBonus());
        System.out.println(em.getSalary());     
        }
}

Compiler looks for reference type before calling any operations on it. em.getBonus() doesn't work because Employee doesn't have a bonus method. But using a cast we can make it work. ((Manager)em.)getBonus()

Reason why compiler looks for the reference type before calling any operation on it is as follows:

Manager[] managers = new Manager[10];

It is legal to convert this array to an Employee[] array:

Employee[] staff = managers; // OK

Sure, why not, you may think. After all, if manager[i] is a Manager, it is also an Employee. But actually, something surprising is going on. Keep in mind that managers and staff are references to the same array.

Now consider the statement

staff[0] = new Employee("John Eipe", ...);

The compiler will cheerfully allow this assignment. But staff[0] and manager[0] are the same reference, so it looks as if we managed to smuggle a mere employee into the management ranks.

That would be very bad — calling managers[0].setBonus(1000) would try to access a nonexistent instance field and would corrupt neighboring memory. To make sure no such corruption can occur, all arrays remember the element type with which they were created, and they monitor that only compatible references are stored into them. For example, the array created as new Manager[10] remembers that it is an array of managers. Attempting to store an Employee reference causes an ArrayStoreException.

Upvotes: 1

biziclop
biziclop

Reputation: 49744

The box analogy is wrong, think of an is a relationship instead.

In the first example, LCD extends Monitor, that is LCD is a Monitor, therefore anywhere where Monitor is expected, LCD is fine. When you think about in real-world terms instead of looking at the code, you realise this is correct. Everything that you can expect a monitor in general to do (e.g. display a picture), an LCD monitor will do.

In the second example LCD is not a Monitor, so you get an error message.

Upvotes: 3

Related Questions