class I {
String s="yes its me:I";
void Mine(){
System.out.println(s);
}
}
class N extends I {
String l="yes its me:N";
void Mine(){
System.out.println(l);
}
}
class T extends N{
String m="yes its me:T";
void Mine(){
System.out.println(m);
}
}
class Test{
public static void main(String[] args) {
I i=new I();
N n=new N();
T t=new T();
I r; // r is a variable of class type I
r=i; // fine here
r.Mine(); //no doubt here
r=n; // heres the problem
r.Mine(); // these are working only
r=t; //with overriding methods existing & no other method exists in all classes
r.Mine();
}
}
还请告诉我:如果我们声明一个类类型的变量,它会做什么(我的意思是,它将通过该类的方法和实例变量的数量或仅方法或实例变量的数量来识别)。
最佳答案
class Vehicle {
Engine myEngine = new Engine();
void start() {
myEngine.start();
}
void stop() {
myEngine.stop();
}
}
class VehicleWithSteering extends Vehicle {
Steering mySteering = new Steering();
void start() {
mySteering.reset();
myEngine.start();
}
void steerLeft() {
mySteering.left();
}
void steerRight() {
mySteering.right();
}
}
如您所见,
VehicleWithSteering
确实具有基本的Vehicle
没有的方法。由于启动此更复杂的车辆涉及不同的例程,因此它也覆盖了void start()
方法。class NoviceDriver {
Vehicle myVehicle;
public NoviceDriver(Vehicle vehicle) {
myVehicle = vehicle;
}
void doSomething() {
myVehicle.start();
myVehicle.stop();
}
}
class AdvancedDriver {
VehicleWithSteering myVehicle;
public NoviceDriver(VehicleWithSteering vehicle) {
myVehicle = vehicle;
}
void doSomethingElse() {
myVehicle.start();
myVehicle.steerLeft();
myVehicle.stop();
}
}
AdvancedDriver
需要基本Vehicle
无法满足的其他功能,因此将始终需要VehicleWithSteering
的实例。class Test{
public static void main(String[] args) {
// Create one basic vehicle
Vehicle a = new Vehicle();
// And one more advanced
VehicleWithSteering b = new VehicleWithSteering();
// A novice driver is satisfied with having a basic vehicle
NoviceDriver x = new NoviceDriver(a);
// The advanced driver however needs more functionality
AdvancedDriver y = new AdvancedDriver(b);
// A novice driver can use the advanced vehicle as well
// But he will not bother about the advanced functionality
NoviceDriver z = new NoviceDriver(b);
}
}
NoviceDriver
仅知道如何访问Vehicle
的方法。但是由于这些方法也出现在VehicleWithSteering
中,因此他也可以使用该方法。 NoviceDriver
甚至都不知道转向的含义,因此他不会触摸任何他不知道的控件。您不能将
AdvancedDriver
与Vehicle
配合使用,因为此方法未包含必需的转向方法。如果
VehicleWithSteering
进行了更高级的改进,则NoviceDriver
和AdvancedDriver
仍可以使用它来执行其有限的任务,因为它仍然提供了必需的基本功能。NoviceDriver
可以访问原始Vehicle
拥有的所有公共方法和属性。它不知道稍后添加的新方法或属性。在这种情况下,它可以看到Engine myEngine
上继承的VehicleWithSteering
属性,但是看不到新的Steering mySteering
属性。至于最后一个问题:这取决于语言。
在Java中,每个类都有其实现的其他继承的类和接口的内部列表。每当将精简类型转换为更原始的类型时,Java都会检查原始类型是否在列表中。此行为也用于其他严格类型的语言,例如C ++,C#和许多其他语言。
另一种概念是鸭式打字。
当我看到一只鸟走路像鸭子,游泳像鸭子,嘎嘎像鸭子一样时,我称那只鸟为鸭子。
一种语言使用Duck-Typing时,它将按名称和签名在对象中查找所请求的方法。这可能在编译时或在运行时发生,在后一种情况下,大多数支持Duck-Typing的语言都会引发异常。
某些语言(例如PHP)和其他各种脚本语言均具有严格的类型检查和Duck-Typing功能。这意味着您既可以选择对继承的类和已实现的接口列表执行严格的类型检查,也可以在省略该检查时默认为Duck-Typing。