使用继承调用方法

时间:2015-11-28 02:47:36

标签: java object inheritance

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

使用boo对象,调用来自fooshowMe的方法。 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!!!");
    }
}

6 个答案:

答案 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是一个ElectricalEngineerComputerEngineer也是Engineer。但并非所有Engineers都保证为ComputerEngineerElectricalEngineer。对于你所知道的,它们可能是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的内容。如果您将对象作为fooboo传递,则无关紧要;多态将确保将调用您创建的对象的实际类型的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)如果没有,那么将在父对象

中调用它