例如,我有一个包含 4 个方法的接口。
如果我在一个类中实现这个接口不完整,那么这个类必须是抽象的。正确的?
例如,我省略了一种方法。所以现在我正在编写一个扩展这个类的子类。现在我实现接口的最后一个方法。
如果我在抽象超类中调用此方法会发生什么?没有什么!有用。但为什么?
如果我写了几个类,扩展这个抽象类并实现接口的第四个方法,会发生什么?会叫哪一个?
接口是您定义方法签名的合同,只有行为和常量,所有方法都是公共和抽象的。
在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
。
请记住,当您实例化子类并将其称为超/抽象类或接口时,它仍然是子类的实例。如果在子类中不可用,则在对象上调用的任何方法都会从子类冒泡到超类。
因此,如果您有:
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 调用方法。
这两个调用 ieandroidGame1.getCloseScreen()
和androidGame2.getCloseScreen()
最终都会调用该方法,AndroidGame
因为它在子类中不可用。
这取决于您创建的对象。超类可以引用子类对象。因此将调用实际对象的方法。
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 类。
如果我在抽象超类中调用此方法会发生什么?没有什么!有用。但为什么?
你不能在abstract
超类上调用这个方法,因为它不能被实例化。您只会在这个抽象超类的子类上调用它,该子类将被迫提供一个实现(或被声明为抽象本身)。
因此,当您调用此方法时,它是由执行的非抽象子类提供的实现。
有趣的是,“AndroidGame”类的一个方法调用了“getStartScreen()”。但是可能有几个类,例如扩展“AndroidGame”的“MrNomGame”。那么会执行哪个方法呢?
执行的方法代码将取决于您调用此方法的实际对象的运行时类型。所以,你可以有这样的代码
AndroidGame game1 = new MrNomGame();
AndroidGame game2 = new SomeOtherGame();
game1.getStartScreen(); // invokes MrNomGame's version
game2.getStartScreen(); // invokes SomeOtherGame's version
并且由于动态绑定,JVM 将调用getStartScreen()
由引用指向的实际对象的类类型实现的 。