首页 文章

实现接口未完成的抽象类

提问于
浏览
3

例如,我有一个有4种方法的接口 .

如果我在类中实现此接口不完整,则该类必须是抽象的 . 对?

例如,我留下了一种方法 . 所以现在我正在编写一个扩展这个类的子类 . 现在我实现接口的最后一个方法 .

如果我在抽象超类中调用此方法会发生什么?没有!有用 . 但为什么?

如果我编写几个类,扩展这个抽象类并实现接口的第四个方法,会发生什么 . 哪一个会被称为?

4 回答

  • 0

    接口是您定义方法签名的合约,只有行为和常量,所有方法都是公共和抽象的 .

    Abstract Class 中定义行为和状态,您可以使用一些实现和抽象方法 .

    例如,您的问题:

    如果我在类中实现此接口不完整,则该类必须是抽象的 . 对?

    例如,我留下一种方法 . 所以现在我正在编写一个扩展这个类的子类 . 现在我实现接口的最后一个方法 . 如果我在抽象超类中调用此方法会发生什么?没有!有用 . 但为什么?

    将在运行时执行运行导致知道什么是类 . 这是多态性 .

    如果我编写几个类,扩展这个抽象类并实现接口的第四个方法,会发生什么 . 哪一个会被称为?

    您在客户端代码中实例化的那个:D

    public interface Operation{ 
     void operation1();
     void operation2();
    
    }
    

    我没有实现operation2

    public abstract class ClaseBase implements Operation{
    //with final im saying childs wont override
     public final void operation1{
       // do something
       operation2();
       // do something
     }
    
    
    }
    

    //必须实现operation2,因为它是一个具体的类

    public class Child extends ClaseBase{
     void operation2(){
       System.out.println("Something");
     }
    
    }
    

    您无法实现AbstractClass .

    在您的客户端代码中

    ClaseBase base = new Child();
    base.operation1(); // and it's gonna to call operation2 in childClass
    

    抽象类对于 Template Method 模式很有用 .

  • 1

    这取决于您创建的对象 . 超类可以引用子类对象 . 因此将调用实际对象的方法 .

    interface A{
    
    public void test1();
    
    public void test2();
    
    }
    
    public abstract class B implements A{
    
    public void test1(){
    
    }
    
    public abstract public void test2();
    
    }
    
    public class C extends B{
    
    public void test2(){
    
    }
    }
    
    B b = new C();
    b.test2();//This works because the object that is refered by B is actually an object of C
    

    事实上你也可以这样做:

    A a = new C();
    a.test1();
    a.test2();
    

    虽然A是一个接口(超类型),但它实际上是指一个具体的实现C(子类型)对象,因此这是有效的 .

    所以在编译时,编译器会检查A / B是否有一个名为test2()的方法,如果是,编译很开心并且编译成功 . 但是在运行时,你在对象和对象上调用test2()方法实际上是C类,它具有完整的实现 .

  • 0

    请记住,当您实例化一个子类并将其称为超级/抽象类或接口时, it's still the instance of the subclass . 如果在子类中不可用,则调用该对象的任何方法都会从子类冒泡到超类 .

    因此,如果你有:

    interface GemeInterface
            getStartScreen()
            getCloseScreen()
    
      abstract class AndroidGame implement GemeInterface
            getCloseScreen()
    
      class MrNomGame extends AndroidGame
            getStartScreen()
    
      class MrPetNomGame  extends AndroidGame
            getStartScreen()
    

    并使用as

    //You can't instantiate AndroidGame hence the it has to be instance of a subclass
    AndroidGame androidGame1 = new MrNomGame ();
    androidGame1.getStartScreen(); 
    
    //You can't instantiate AndroidGame hence the it has to be instance of a subclass
    AndroidGame androidGame2 = new MrPetNomGame ();
    androidGame2.getStartScreen();
    

    然后它也可以作为 androidGame1.getStartScreen() --> calls the method from MrNomGame, while androidGame2.getStartScreen() --> calls the method from MrPetNomGame .

    这两个调用,即 androidGame1.getCloseScreen()androidGame2.getCloseScreen() 将最终从 AndroidGame 调用该方法,因为它在子类中不可用 .

  • 0

    如果我在抽象超类中调用此方法会发生什么?没有!有用 . 但为什么?

    您无法在 abstract 超类上调用此方法,因为它无法实例化 . 你只会在这个抽象超类的子类上调用它,它将被迫提供一个实现(或者被声明为抽象本身) .

    因此,当您调用此方法时,它将由执行的非抽象子类提供 .

    有趣的是,'AndroidGame'类的方法调用'getStartScreen()' . 但是可能有几个类似'MrNomGame'的类扩展了'AndroidGame' . 那么将执行哪种方法?

    执行的方法代码取决于您调用此方法的实际对象的 runtime 类型 . 所以,你可以有这样的代码

    AndroidGame game1 = new MrNomGame();
    AndroidGame game2 = new SomeOtherGame();
    
    game1.getStartScreen(); // invokes MrNomGame's version
    game2.getStartScreen(); // invokes SomeOtherGame's version
    

    并且由于 dynamic binding ,JVM将调用由参考指向的实际对象的类类型实现的 getStartScreen() .

相关问题