OOP Java:可以将子类返回给父类吗?
我是 OOP 的新手,所以我有一个关于类何时扩展
另一个类的愚蠢问题。
这是我的例子:
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(){
}
}
}
我对上面的代码有一个问题:因为 LCD
是从 Monitor
扩展的,并且 LCD
有 Monitor 所做的一些其他属性/方法不是。那么,LCD
是 Monitor
的子级,对吧?
这意味着你试图把一个“大盒子”放在一个“小盒子”上。那么,为什么当我返回新的 LCD
时,Eclipse 不会像我只使用 class LCD {
时那样注意到错误。
谢谢 :)
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 :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在第二种(错误)情况下,您忘记声明
LCD
实际上扩展了Monitor
。您只是定义了一个“正常”的独立类 - 因此new LCD()
不是Monitor
的实例。如果您像这样声明
LCD
类,编译器应该会很高兴:Edit (回应评论):
LCD
根本不是问题与Monitor
相比,code> 类具有额外的属性/方法。将调用getMonitor()
的代码,只关心它是否获得Monitor
返回 - 也就是说,具有Monitor()
的所有方法、属性和行为的东西。代码>监视器。因此,如果您的
Monitor
类上有turnOff
和displayBitmap(int[][] data)
方法,那么您的LCD 类也会有这些方法。当需要时,
LCD
的任何实例都可以充当Monitor
- 这是 OO 语言中子类化的基本原则。因此,每当需要Monitor
时,您都可以给它一个LCD
,或者一个CRT
或SamsungLCD
实例如果你有这些,编译器可以确信正确的方法/属性将存在并且可以被调用。(从技术上讲,如果您喜欢正式定义,那么这就是 里氏替换原则,但您不需要如此详细地理解它。)
In your second (error) case, you've forgotten to declare that
LCD
does in fact extendMonitor
. You're just defining a "normal", standalone class - and so anew LCD()
is not an instance ofMonitor
.The compiler should be happy if you declare the
LCD
class like this:Edit (in response to comment): It's not a problem at all that the
LCD
class has extra properties/methods compared toMonitor
. The code that's going to callgetMonitor()
, only really cares that it gets aMonitor
back - that is, something that has all the methods and properties and behaviour of aMonitor
.So if you had
turnOff
anddisplayBitmap(int[][] data)
methods on yourMonitor
class, then yourLCD
class will also have these methods. Any instance ofLCD
can behave as aMonitor
when one is needed - this is the basic principle of subclassing in OO languages. So whenever something wants aMonitor
, you can give it anLCD
, or an instance ofCRT
orSamsungLCD
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.)
盒子的类比是错误的,应该将其视为
是
关系。在第一个示例中,
LCD 扩展了 Monitor
,即LCD 是一个 Monitor
,因此在任何需要 Monitor 的地方,LCD 都可以。当您考虑现实世界而不是查看代码时,您会意识到这是正确的。一般情况下,您可以期望显示器执行的所有操作(例如显示图片),液晶显示器都可以执行。在第二个示例中,LCD 不是监视器,因此您会收到一条错误消息。
The box analogy is wrong, think of an
is a
relationship instead.In the first example,
LCD extends Monitor
, that isLCD 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.
将继承理解为“是”关系。这是我在新手时期用来理解继承的一个简单例子。
编译器在调用引用类型上的任何操作之前会查找引用类型。
em.getBonus() 不起作用,因为 Employee 没有奖金方法。
但使用演员表我们可以让它发挥作用。
((Manager)em.)getBonus()
编译器在调用引用类型上的任何操作之前查找引用类型的原因如下:
Manager[] Managers = new Manager[10];
将此数组转换为 Employee[] 数组是合法的:
Employee[] Staff = Managers; // 好吧
,当然,你可能会想为什么不呢。毕竟,如果 manager[i] 是经理,那么它也是员工。但实际上,令人惊讶的事情正在发生。请记住,经理和员工是对同一数组的引用。
现在考虑语句
Staff[0] = new Employee("John Eipe", ...);
编译器会很高兴地允许这个分配。
但是,staff[0] 和 manager[0] 是相同的引用,因此看起来我们似乎成功地将一名员工偷偷带入了管理层
行列。
这将是非常糟糕的——调用managers[0].setBonus(1000)会尝试访问
不存在的实例字段会损坏相邻的内存。
为了确保不会发生此类损坏,所有数组都会记住元素类型
它们被创建,并且它们监视仅兼容的引用被存储到
他们。例如,创建为 new Manager[10] 的数组会记住它是一个数组
经理。尝试存储 Employee 引用会导致 ArrayStoreException。
Understand Inheritance as a "is a" relationship. Here is a simple example I used to understand inheritance during my novice years.
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.
您的方法
getMonitor
返回“Monitor”类型。当您使用监视器扩展您的 LCD 类时,您是在说 LCD 是一个监视器。
当您删除扩展时,LCD 类将变为普通类,而不是监视器类型。
如果您将 getMonitor 修改为
错误就会消失。
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
The error will go.