我创建了一个非常简单的程序来测试在通过继承调用该方法时将调用哪个方法。
Class boo extends foo
。
使用boo
对象,调用来自foo
类showMe
的方法。 showMe
类中的foo
方法调用方法showText
以在屏幕上显示文本。
boo
类会覆盖showText
方法并显示不同的文字。
我的预测是foo
类中的方法将被调用而不是boo
类中的重写版本。我错了,调用了boo
类中的方法。有人可以解释一下这是怎么回事。此外,我想知道如何在foo
类中调用该方法,即使我在boo
类中有一个重写方法。
boo class
public class boo extends foo
{
public static void main(String[] args)
{
boo main = new boo();
main.showMe();
}
@Override
public void showText()
{
System.out.println("Bruhhh!!!");
}
}
foo class
public class foo
{
protected void showMe()
{
showText();
}
public void showText()
{
System.out.println("Bruhhh Part 2!!!");
}
}
答案 0 :(得分:1)
调用boo中的方法是因为main
的类型为boo
。
如果您希望打印foo
中的那个,则应将boo main = new boo();
更改为foo main = new foo();
继承是一棵树。如果您尝试将其与现实生活中的树木相关联,例如进化,车辆,专业和相关分支,则更容易理解。例如,有许多类型的工程师。首先是Engineer
,然后是ElectricalEngineer
,然后是ComputerEngineer
。
public class Engineer {
public void do() {
System.out.println("I build stuff");
}
}
public class ElectricalEngineer {
public void do() {
System.out.println("I build electronics");
}
}
public class ComputerEngineer {
public void do() {
System.out.println("I build computers");
}
}
Engineer eng = new Engineer();
ElectricalEngineer ee = new ElectricalEngineer();
ComputerEngineer ce = new ComputerEngineer();
eng.do(); // prints "I build stuff"
ee.do(); // prints "I build electronics"
ce.do(); // prints "I build computers"
// eng is of type Engineer
// ee is of type ElectricalEngineer
// ce is of type ComputerEngineer
Engineer ee2 = new ElectricalEngineer();
Engineer ce2 = new ComputerEngineer();
ee2.do(); // prints "I build electronics"
ce2.do(); // prints "I build computers"
此处,ee2
的类型为Engineer
,但它实际上是ElectricalEngineer
。它将调用其重写的do()
方法。与ce2
ElectricalEngineer ce3 = new ComputerEngineer();
ce3.do(); // prints "I build computers"
但如果你这样做:
ElectricalEngineer ee3 = new Engineer();
ComputerEngineer ce4 = new ElectricalEngineer();
ComputerEngineer ce5 = new Engineer();
因为ElectricalEngineer
是工程师,所以他们都会收到错误。 ComputerEngineer
是一个ElectricalEngineer
。 ComputerEngineer
也是Engineer
。但并非所有Engineers
都保证为ComputerEngineer
或ElectricalEngineer
。对于你所知道的,它们可能是CivilEngineer
。
答案 1 :(得分:1)
除了Alex的答案之外,如果您仍想在实例化boo时从boo调用foo的方法,则必须在boo
中创建另一种方法。所以你的嘘声成为:
public class boo extends foo
{
public static void main(String[] args)
{
boo main = new boo();
main.showMe();
}
@Override
public void showText()
{
System.out.println("Bruhhh!!!");
}
public void showFooText(){
super.showText();
}
}
调用showFooText()
将显示来自foo的文本。
答案 2 :(得分:1)
从你的问题中不完全清楚你究竟在寻找什么,但我认为这涵盖了你的大多数情况:
public class boo extends foo
{
public static void main(String[] args)
{
//Create & use a "foo" object
System.out.println("Use foo's showText()");
foo main1 = new foo();
main1.showMe();
System.out.println("=====================");
//Create & use a "boo" object (but pass it around as a "foo")
System.out.println("Use boo's showText()");
foo main2 = new boo();
main2.showMe();
System.out.println("=====================");
//Create & use a "boo" object
System.out.println("Use boo's showText()");
boo main3 = new boo();
main3.showMe();
}
@Override
public void showText()
{
System.out.println("Bruhhh!!!");
super.showText();
}
}
被调用的showText
版本取决于main
的类型。如果您查看上面代码中的三个示例,创建对象的new
语句将控制将调用showText
的内容。如果您将对象作为foo
或boo
传递,则无关紧要;多态将确保将调用您创建的对象的实际类型的showText
。
要回答您的其他问题,您可以使用super.method()
语法从子类调用父类方法。
答案 3 :(得分:1)
使用this
对象的运行时类解析方法调用,而不是this
引用的编译时类型。
因此,当showMe()
调用showText()
时,运行时将确定this
对象的运行时类,即boo
,并查找该类中的方法。
调用重写方法的唯一方法是在子类中使用super
。例如,您可以这样做:
class boo extends foo {
@Override
public void showMe() {
super.showText();
}
让showMe()
方法调用重写的超级实现。
答案 4 :(得分:1)
如果
//SuperClass
class A()
{
public void methodExample()
{
//Origional Functionality
}
}
//SubClass
class B extends A()
{
@Override
public void methodExample()
{
//New Functionality
}
}
据我所知,班级' B'不能指望其超类中的任何一个(或更一般的,未被覆盖的)功能' A'如果' B'已使用新功能覆盖该方法。如果您仍然需要该功能,则可能需要在超类中创建一个不会溢出的方法。
答案 5 :(得分:1)
Boo list = new Boo();
list.showText();
Foo list2 = new Boo();
list2.showText();
Foo list3 = new Foo();
list3.showText();
// Boo list4 = new Foo(); Incorrect!!
结果
Bruhhh!!!
Bruhhh!!!
Bruhhh Part 2!!!
顺便说一下,In Java Class名称必须以 大写 !!
开头那么,它是如何运作的? :理解Java中的对象和实例
在第一段代码中
Boo list = new Boo();
list.showText();
实际上,在Boo
类中调用了list.showText()方法(Boo
类的所有方法和数据都在内存中实例化)
1)如果有@override showText()
,则会在Boo
类中调用它
2)如果没有,那么将在父对象
在第二段代码中
Foo list2 = new Boo();
list2.showText();
实际上,list.showText()方法在Boo
类中调用,但使用了Foo
对象
(什么?这意味着Boo
类必须扩展 Foo
类才能使用Foo Object !!而list2只能调用Foo
类中的方法)
1)如果@override showText()
中有Boo
,则会在Boo
类中调用它
2)如果没有,那么将在父对象