例如,我有一个包含4种方法的界面。
如果我在类中实现此接口不完整,则该类必须是抽象的。对?
例如,我留下一种方法。所以现在我正在编写一个扩展这个类的子类。现在我实现接口的最后一个方法。
如果我在抽象超类中调用此方法会发生什么?没有!有用。但为什么?
如果我写了几个类,扩展这个抽象类并实现接口的第四个方法会发生什么。会叫哪一个?
答案 0 :(得分:1)
接口是您定义方法签名的合约,只有行为和常量,所有方法都是公共和抽象的。
在Abstract Class
中定义行为和状态,您可以使用一些实现和抽象方法。
例如,您的问题:
如果我在类中实现此接口不完整,则该类必须是 抽象。正确?
右
例如,我留下一种方法。所以现在我正在写一个子类 这扩展了这个类。现在我实现了最后一个方法 接口
如果我在抽象超类中调用此方法会发生什么? 没有!有用。但为什么呢?
运行执行中的run run会知道什么是类。这是多态性。
如果我写几个类,扩展这个摘要会发生什么 类和实现接口的第四种方法。哪一个会 被称为?
您在客户端代码中实例化的那个: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 :(得分:0)
请记住,当您实例化一个子类并将其称为超级/抽象类或接口时,它仍然是子类的实例。如果在子类中不可用,则调用该对象的任何方法都会从子类冒泡到超类。
因此,如果你有:
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
的方法,因为它在子类中不可用。
答案 2 :(得分:0)
这取决于您创建的对象。超类可以引用子类对象。因此,将调用实际对象的方法。
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 :(得分:0)
如果我在抽象超类中调用此方法会发生什么?没有!有用。但为什么?
您无法在abstract
超类上调用此方法,因为它无法实例化。你只会在这个抽象超类的子类上调用它,它将被强制提供一个实现(或者自己声明为抽象)。
因此,当您调用此方法时,它将执行非抽象子类提供的实现。
有趣的是,'AndroidGame'类的方法调用'getStartScreen()'。但是可能有几个类似'MrNomGame'的类扩展了'AndroidGame'。那么将执行哪种方法?
执行的方法代码取决于您调用此方法的实际对象的 运行时 类型。所以,你可以有这样的代码
AndroidGame game1 = new MrNomGame();
AndroidGame game2 = new SomeOtherGame();
game1.getStartScreen(); // invokes MrNomGame's version
game2.getStartScreen(); // invokes SomeOtherGame's version
由于 动态绑定 ,JVM将调用由引用所指向的实际对象的类类型实现的getStartScreen()
。