【问题标题】:abstract classes which implements an incomplete interface实现不完整接口的抽象类
【发布时间】:2013-06-15 04:56:48
【问题描述】:

例如,我有一个包含 4 个方法的接口。

如果我在一个类中实现这个接口不完整,那么这个类必须是抽象的。正确的?

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

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

如果我写了几个类,扩展这个抽象类并实现接口的第四个方法,会发生什么?会调用哪一个?

【问题讨论】:

    标签: java android interface abstract


    【解决方案1】:

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

    Abstract Class 中定义行为和状态,可以有一些实现和抽象方法。

    例如你的问题:

    如果我在一个类中实现这个接口不完整,那么这个类必须是 抽象的。对吧?

    例如,我省略了一种方法。所以现在我正在写一个子类 它扩展了这个类。现在我实现的最后一个方法 界面。

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

    会在运行时执行中运行原因知道什么是类。这是多态性。

    如果我写几个类,扩展这个摘要会发生什么 类并实现接口的第四个方法。哪个会 被召唤?

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

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

    我没有实现操作2

    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 模式很有用。

    【讨论】:

    • 现在我明白了。感谢大家的帮助:-)
    • 不应该 Child 执行 operation1() 吗? (并且ClaseBase 应该在operation2() 正文中调用operation1())。
    【解决方案2】:

    这取决于您创建的对象。超类可以引用子类对象。所以实际对象的方法会被调用。

    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 类。

    【讨论】:

      【解决方案3】:

      请记住,当您实例化子类并将其称为超/抽象类或接口时,它仍然是子类的实例。如果在子类中不可用,则在对象上调用的任何方法都会从子类冒泡到超类。

      如果你有:

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

      并用作

      //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() --> 从 MrNomGame 调用方法,而 androidGame2.getStartScreen() --> 从 MrPetNomGame 调用方法

      androidGame1.getCloseScreen()androidGame2.getCloseScreen() 这两个调用最终都会调用来自 AndroidGame 的方法,因为它在子类中不可用。

      【讨论】:

      • 我的问题涉及一本面向 android 开发人员(初学者)的书中的示例。我的问题没有回答。我写下例子: 那就是入口点:public class MrNomGame extends AndroidGame { public Screen getStartScreen() { return new LoadingScreen(this); } }
      • 我的问题涉及一本面向 android 开发人员(初学者)的书中的示例。我的问题没有回答。我写下这个例子: 那是入口点:public class MrNomGame extends AndroidGame { public Screen getStartScreen() { return new LoadingScreen(this); } } 'AndroidGame' 是一个抽象类,它扩展了'Activity-class'。但是“AndroidGame”类是抽象的,因为它没有实现“AndroidGame”实现的接口中规定的方法“getStartScreen()”。但是“MrNomGame”类实现了“getStartScreen()”。
      • 有趣的是,“AndroidGame”类的一个方法调用了“getStartScreen()”。但是可能有多个类,例如扩展“AndroidGame”的“MrNomGame”。那么会执行哪个方法呢?
      • @PeterPanne 如果我理解正确,那就是我正在尝试解释的内容。 Abstract1 是抽象类,但不实现 method2 而抽象类的子类实现。
      • @PeterPanne:回到你的上一个问题。 “它将执行哪种方法”。 您永远无法实例化抽象类。如果您有一个通过抽象类(即 AndroidGame)引用的对象,它必须是其中一个子类的实例。它可能是MrNomGame 类或其他子类的实例。在运行时,它将执行子类中的方法,从该子类中实例化它。我的答案的最后部分解释了相同的内容。
      【解决方案4】:

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

      您不能在abstract 超类上调用此方法,因为它不能被实例化。你只会在这个抽象超类的一个子类上调用它,它会被强制提供一个实现(或被声明为抽象本身)。

      因此,当您调用此方法时,它会执行由 非抽象子类 提供的实现。

      有趣的是,“AndroidGame”类的一个方法调用了“getStartScreen()”。但是可能有几个类,例如扩展“AndroidGame”的“MrNomGame”。那么会执行哪个方法呢?

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

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

      并且由于动态绑定,JVM 将调用getStartScreen(),正如引用指向的实际对象的类类型所实现的那样。

      【讨论】:

        猜你喜欢
        • 2012-07-17
        • 2012-01-20
        • 1970-01-01
        • 2014-08-18
        • 1970-01-01
        • 2014-02-05
        • 1970-01-01
        • 2020-10-20
        • 2012-09-02
        相关资源
        最近更新 更多