在抽象类中调用非抽象方法的Java问题

4

我有3个类。这似乎是一个基本的问题。但是我在谷歌上找不到答案。

public abstract class Test {

    void t1()
    {
        System.out.println("super");

    }

}
 public class concret extends Test{

    void t1()
    {
        System.out.println("child");

    }
    void t2()
    {
        System.out.println("child2");

    }

}

public class run {
    public static void main(String[] args) {
        Test t=new concret();

        t.t1();
    }

}

如何调用抽象类t1中的方法?由于不能从抽象类创建对象,所以我该如何在抽象类中调用t1方法呢? 谢谢。


3
我没有看到任何抽象类。 - rgettman
抽象类在哪里? - Sarthak Mittal
1
在concret的t1方法中,您可以调用super.t1(),但一旦被覆盖,就没有其他方法了。 - scrappedcola
9个回答

12

你可以创建一个不覆盖该方法的具体类,或者在覆盖该方法的具体类中调用super.t1()。例如:

void t1()
{
    super.t1(); // First call the superclass implementation
    System.out.println("child");
}

如果你只有一个覆盖了方法的对象实例,你就无法从“外部”调用原始方法,因为这会破坏封装性...覆盖的目的是替换原始方法的行为。


谢谢。我理解了...我不明白封装部分是什么意思? - Dilis
请查看 why-is-super-super-method-not-allowed-in-java 以了解它如何违反封装性。 - Pshemo

3

你应该能够使用以下方法来完成

Test test = new Test(){};
test.t1();

1
抽象类指在“class”关键字前使用“abstract”修饰符的类。这意味着您可以声明抽象方法,这些方法只在具体类中实现。
例如:
public abstract class Test {
     public abstract void foo();
}

public class Concrete extends Test {
    public void foo() {
        System.out.println("hey");
    }
}

1
这并没有回答问题。OP想知道如何在派生类的实例上调用基类方法的代码,如果派生类覆盖了这个方法。基类是抽象的,实际上与OP所描述的问题无关。 - Pshemo

1
看下面的测试:
public abstract class BaseClass {

    public void doStuff() {
        System.out.println("Called BaseClass Do Stuff");
    }

    public abstract void doAbstractStuff();
}

public class ConcreteClassOne extends BaseClass{

    @Override
    public void doAbstractStuff() {
        System.out.println("Called ConcreteClassOne Do Stuff");
    }
}

public class ConcreteClassTwo extends BaseClass{

    @Override
    public void doStuff() {
        System.out.println("Overriding BaseClass Do Stuff");
    }
    @Override
    public void doAbstractStuff() {
        System.out.println("Called ConcreteClassTwo Do Stuff");
    }
}

public class ConcreteClassThree extends BaseClass{

    @Override
    public void doStuff() {
        super.doStuff();
        System.out.println("-Overriding BaseClass Do Stuff");
    }
    @Override
    public void doAbstractStuff() {
        System.out.println("Called ConcreteClassThree Do Stuff");
    }
}

public class Test {

    public static void main(String[] args) {
        BaseClass a = new ConcreteClassOne();
        a.doStuff(); //Called BaseClass Do Stuff
        a.doAbstractStuff(); //Called ConcreteClassOne Do Stuff

        BaseClass b = new ConcreteClassTwo();
        b.doStuff(); //Overriding BaseClass Do Stuff
        b.doAbstractStuff(); //Called ConcreteClassTwo Do Stuff

        BaseClass c = new ConcreteClassThree();
        c.doStuff(); //Called BaseClass Do Stuff
                        //-Overriding BaseClass Do Stuff
        c.doAbstractStuff(); //Called ConcreteClassThree Do Stuff
    }
}

1
使用关键字'super'来实现。
void t1()
     {  super.t1();
        System.out.println("child");

    }

请确保在重写方法中使用该方法。


0

你的代码似乎调用了t1()。然而,这会调用具体类中已经覆盖了抽象t1()的方法。

如果你希望从主代码中调用抽象t1方法,请不要在具体类中覆盖t1()。

或者你可以在具体类中创建一个方法,例如:

    public void invokeSuperT1(){
      super.t1();
    }

0
创建一个匿名内部类,
抽象类:
 abstract class  Test{
        abstract void t();
        public void t1(){
            System.out.println("Test");
        }
    }

以下是如何创建匿名内部类的方法:

Test test = new Test() {

            @Override
            void t() {
                //you can throw exception here, if you want
            }
        };

通过为抽象类创建的对象调用类。

test.t1();

0

虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。- 来自审查 - K.Mat

0
抽象类用于要求从我们的抽象类继承的每个类都应该实现该抽象方法,因此必须实现该方法,否则会在编译时出错。
void t1()
    {
        super.t1; // means the parent methods
        System.out.println("child");
    } 

例如:Bird类有一个sing()方法,还有其他继承自它的类,如麻雀、鸽子、鸭子,它们都有sing方法,因此我们将Bird类设为抽象类,并在其中将sing()方法设为抽象方法,这样实现Bird类的每个子类都应该有一个具有其自己实现的sing()方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接