Java 将实例化分配给父类和派生类之间的区别
如果我声明这两个类:Java 将实例化分配给父类和派生类之间的区别,java,Java,如果我声明这两个类: public class A { // attributes } public class B extends A { // attributes } A obj1 = new B(); B obj2 = new B(); 这两个实例化之间有什么区别?在实例化中没有区别。在这两种情况下,您都是在堆上为B对象分配空间 差异在于参考变量的赋值和类型 A obj = new B(); 在这种情况下,参考变量obj的类型为A(父变量)。因此,在obj上调用行为时,只能
public class A {
// attributes
}
public class B extends A {
// attributes
}
A obj1 = new B();
B obj2 = new B();
这两个实例化之间有什么区别?在实例化中没有区别。在这两种情况下,您都是在堆上为
B
对象分配空间
差异在于参考变量的赋值和类型
A obj = new B();
在这种情况下,参考变量obj
的类型为A
(父变量)。因此,在obj
上调用行为时,只能调用A
中存在的方法
B obj = new B();
在这种情况下,参考变量
obj
的类型为B
(child)。因此,当在obj
上调用行为时,可以调用子B
从其父A
继承的方法,也可以调用仅存在于B
中的方法。在实例化中没有区别。在这两种情况下,您都是在堆上为B
对象分配空间
差异在于参考变量的赋值和类型
A obj = new B();
在这种情况下,参考变量obj
的类型为A
(父变量)。因此,在obj
上调用行为时,只能调用A
中存在的方法
B obj = new B();
在这种情况下,参考变量obj
的类型为B
(child)。因此,当在obj
上调用行为时,可以调用子B
从其父A
继承的方法,也可以调用仅存在于B
中的方法。实例化是相同的。在这两种情况下,您都在创建一个新B()
作业是不同的。由于B
是a
,因此可以将B
类型的任何表达式指定给a
类型的变量。无需执行显式强制转换即可执行此操作,因此:
允许将表达式的值指定给变量;表达式的类型必须转换为变量的类型
在您的示例中,如果S
是T
的子类型,则执行一个允许将引用类型S
转换为引用类型T
。编译器会自动为您执行此操作,因为这是一个扩展的转换:即,在没有ClassCastException
的情况下,它将始终成功
Java需要考虑到这一点才能做到这一点,这允许您将类型S
视为其超类型T
(例如,将Cat
或Dog
视为动物
);这反过来又允许您将通用行为(或通用契约——有关接口的注释,请参见下文)放入超类型
在运行时,实际类型是已知的,并且调用实际类型的方法而不是超类型方法。因此,对于动物a=新猫()运行时知道a
是Cat
,并在Cat
上调用sleep
的实现,而不是在Animal
上调用
public class Animal { public void sleep() { /* close eyes */ } }
public class Cat extends Animal { public void sleep() { /* curlUpAndSleep */ } }
public class Dog extends Animal { public void sleep() { /* stretchOutAndSleep */ } }
...
public void putToBed(Animal a) { a.sleep(); }
...
Animal a1 = new Cat(); // curls up and sleeps
Animal a2 = new Dog(); // stretches out and sleeps - my dog obviously thinks he's a cat
putToBed(a1); putToBed(a2);
整个概念也适用于允许您将通用约定应用于不共享超类型关系的对象的接口:
public interface Sleepable { public void sleep(); }
public class Cat implements Sleepable { public void sleep() { /* curlUpAndSleep */ } }
public class Dog implements Sleepable { public void sleep() { /* stretchOutAndSleep */ } }
...
public void putToBed(Sleepable a) { a.sleep(); }
实例化是相同的。在这两种情况下,您都在创建一个新B()
作业是不同的。由于B
是a
,因此可以将B
类型的任何表达式指定给a
类型的变量。无需执行显式强制转换即可执行此操作,因此:
允许将表达式的值指定给变量;表达式的类型必须转换为变量的类型
在您的示例中,如果S
是T
的子类型,则执行一个允许将引用类型S
转换为引用类型T
。编译器会自动为您执行此操作,因为这是一个扩展的转换:即,在没有ClassCastException
的情况下,它将始终成功
Java需要考虑到这一点才能做到这一点,这允许您将类型S
视为其超类型T
(例如,将Cat
或Dog
视为动物
);这反过来又允许您将通用行为(或通用契约——有关接口的注释,请参见下文)放入超类型
在运行时,实际类型是已知的,并且调用实际类型的方法而不是超类型方法。因此,对于动物a=新猫()运行时知道a
是Cat
,并在Cat
上调用sleep
的实现,而不是在Animal
上调用
public class Animal { public void sleep() { /* close eyes */ } }
public class Cat extends Animal { public void sleep() { /* curlUpAndSleep */ } }
public class Dog extends Animal { public void sleep() { /* stretchOutAndSleep */ } }
...
public void putToBed(Animal a) { a.sleep(); }
...
Animal a1 = new Cat(); // curls up and sleeps
Animal a2 = new Dog(); // stretches out and sleeps - my dog obviously thinks he's a cat
putToBed(a1); putToBed(a2);
整个概念也适用于允许您将通用约定应用于不共享超类型关系的对象的接口:
public interface Sleepable { public void sleep(); }
public class Cat implements Sleepable { public void sleep() { /* curlUpAndSleep */ } }
public class Dog implements Sleepable { public void sleep() { /* stretchOutAndSleep */ } }
...
public void putToBed(Sleepable a) { a.sleep(); }
万一
A a = new B()
已创建类型为B的Instance,但引用为父类型。使用它,您无法访问特定于B类型的字段或调用方法。
A a = new B()
已创建类型为B的Instance,但引用为父类型。使用它,您无法访问特定于B类型的字段或调用方法。让我在您的问题中添加一些代码
public class A{
void base(){
print("base method");
}
}
public class B extends A{
void child(){
print("child method");
}
}
.......
A obj1 = new B();
B obj2 = new B();
现在按对象调用这两个方法
obj1.base(); //base method
obj1.child(); //create compile time error
因为obj1是B类的对象,但引用是A类的….
obj1只能调用类A中的方法
//but obj2 can call both methods as it inherits Class A and also having reference of its own.
obj2.base(); //base method
obj2.child(); // child method
让我在你的问题中添加一些代码
public class A{
void base(){
print("base method");
}
}
public class B extends A{
void child(){
print("child method");
}
}
.......
A obj1 = new B();
B obj2 = new B();
现在按对象调用这两个方法
obj1.base(); //base method
obj1.child(); //create compile time error
因为obj1是B类的对象,但引用是A类的….
obj1只能调用类A中的方法
//but obj2 can call both methods as it inherits Class A and also having reference of its own.
obj2.base(); //base method
obj2.child(); // child method
多态性和接口编程。开始。在B
中创建一个在a
中不存在的全新方法。在这两种情况下都试着调用它。接下来创建一个具有相同属性的方法