Java 使用继承的方法调用

Java 使用继承的方法调用,java,object,inheritance,Java,Object,Inheritance,我创建了一个非常简单的程序来测试当通过继承调用该方法时将调用哪个方法。 类boo扩展了foo 使用boo对象,调用fooclassshowMe中的方法showMe方法调用方法showText在屏幕上显示文本 boo类重写showText方法并显示不同的文本 我的预测是foo类中的方法将被调用,而不是boo类中的重写版本。我错了,调用了boo类中的方法。谁能解释一下这是怎么发生的吗。另外,我想知道如何调用foo类中的方法,即使我在boo类中有一个被重写的方法 boo类 public cla

我创建了一个非常简单的程序来测试当通过继承调用该方法时将调用哪个方法。
类boo扩展了foo

使用
boo
对象,调用
foo
class
showMe
中的方法<
foo
类中的code>showMe方法调用方法
showText
在屏幕上显示文本

boo
类重写
showText
方法并显示不同的文本

我的预测是
foo
类中的方法将被调用,而不是
boo
类中的重写版本。我错了,调用了
boo
类中的方法。谁能解释一下这是怎么发生的吗。另外,我想知道如何调用
foo
类中的方法,即使我在
boo
类中有一个被重写的方法

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 class foo
{
    protected void showMe()
    {
        showText();
    }

    public void showText()
    {
        System.out.println("Bruhhh Part 2!!!");
    }
}

调用boo中的方法是因为
main
的类型为
boo

如果希望它打印
foo
中的一个,则应更改
boo main=new boo()
foomain=newfoo()

继承是一棵树。如果你试着把它和现实生活中的树联系起来,比如进化、交通工具、职业和相关的分支,就会更容易理解。例如,有许多类型的工程师。起初有
工程师
,然后是
电气工程师
,然后是
计算机工程师

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
,但实际上是
electrialengineer
。它将调用其重写的
do()
方法。与ce2相同

ElectricalEngineer ce3 = new ComputerEngineer();

ce3.do(); // prints "I build computers"
但如果你这样做了:

ElectricalEngineer ee3 = new Engineer();
ComputerEngineer ce4 = new ElectricalEngineer();
ComputerEngineer ce5 = new Engineer();

因为
电气工程师
是工程师,所以所有这些都会出错。
计算机工程师
电气工程师
<代码>计算机工程师
也是一名
工程师
。但并非所有的
工程师
都保证是
计算机工程师
电气工程师
。据您所知,它们可能是
CivilEngineer

调用boo中的方法是因为
main
属于
boo
类型

如果希望它打印
foo
中的一个,则应更改
boo main=new boo()
foomain=newfoo()

继承是一棵树。如果你试着把它和现实生活中的树联系起来,比如进化、交通工具、职业和相关的分支,就会更容易理解。例如,有许多类型的工程师。起初有
工程师
,然后是
电气工程师
,然后是
计算机工程师

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
,但实际上是
electrialengineer
。它将调用其重写的
do()
方法。与ce2相同

ElectricalEngineer ce3 = new ComputerEngineer();

ce3.do(); // prints "I build computers"
但如果你这样做了:

ElectricalEngineer ee3 = new Engineer();
ComputerEngineer ce4 = new ElectricalEngineer();
ComputerEngineer ce5 = new Engineer();

因为
电气工程师
是工程师,所以所有这些都会出错。
计算机工程师
电气工程师
<代码>计算机工程师
也是一名
工程师
。但并非所有的
工程师
都保证是
计算机工程师
电气工程师
。据你所知,它们可能是
CivilEngineer

除了Alex的回答之外,如果你仍然想在只实例化boo的同时从boo调用foo的方法,你必须在
boo
中创建另一个方法。因此,您的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的文本。

除了Alex的答案之外,如果您仍然想从boo调用foo的方法,同时只实例化boo,则必须在
boo
中创建另一个方法。因此,您的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的文本。

您的问题并不完全清楚您到底在寻找什么,但我认为这涵盖了您的大多数情况:

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()
语法从子类调用父类方法。

您的问题并不完全清楚您到底在寻找什么,但我认为这涵盖了您的大多数情况:

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()
语法从子类调用父类方法。

方法调用使用
this
对象的运行时类,而不是
this
引用的编译时类型来解决

因此,当
showMe()
调用
showText()
时,运行时确定
对象的运行时类,即
boo
,并在该类中查找方法

调用重写方法的唯一方法是在子类中使用
super
。例如,您可以执行以下操作:

class boo extends foo {
    @Override 
    public void showMe() {
        super.showText();
    }
让showMe()方法调用重写的超级实现。