343*_*ark 2 java oop inheritance object
考虑以下:
public class parent {
int x;
parent() {
x = 5;
}
}
public class child extends parent {
int y;
child() {
super();
y = 10;
}
public static void main(String[] args) {
parent p = new child();
System.out.println(p.y);//can't access variable y
}
Run Code Online (Sandbox Code Playgroud)
}
这里,在父类的对象上调用子类的构造函数.在进行Android编程时,我多次遇到过这种情况.我的问题是为什么允许这样做?子类的构造函数可能初始化其他成员,但是他们的蓝图可能没有像上面的情况那样在父类中定义.
T.J*_*der 13
为什么允许使用子类的构造函数实例化父类对象?
那不是那里发生的事情.在这一行:
parent p = new child();
Run Code Online (Sandbox Code Playgroud)
...你正在创建一个child对象,而不是一个parent对象.您用来引用它的变量p具有类型parent,这意味着您只能parent通过该引用使用东西,但该对象是一个child对象.该对象确实有一个y,您无法通过它访问它p.你可以通过这样做看到:
parent p = new child();
System.out.println( ((child)p).y );
Run Code Online (Sandbox Code Playgroud)
通过告诉编译器我们知道即使它是类型(通过"强制转换")p引用,我们也可以访问它的特定部分.(当你有另一种选择时,这不是一个好习惯.)childparentchild
这种能够使你所拥有的东西与它实际上的东西之间存在差异(在约束内)的能力被称为"多态"(采用多种形式),并且是面向对象编程的核心.
考虑:
class Animal {
}
class Dog extends Animal {
}
class Cat extends Animal {
}
Run Code Online (Sandbox Code Playgroud)
所有Dogs都是Animals,所有s都是s,Cat但Dogs不是Cats.假设您经营一家宠物店并希望存储您手头的动物清单:
List<Animal> animals;
Run Code Online (Sandbox Code Playgroud)
条目可以是类型的对象Animal 或其任何子类型,例如Dog和Cat.这使您可以在这些类型上具有动物的共同方面Animal,然后只有Dog- 或Cat- 特定方面(属性或行为).你可以浏览你Animal的动物列表,而不必担心它们是Dogs还是Cats.
除了作为构造函数中实例化的一部分之外,不会进行父类的实例化child。您在这里得到一个实例,那就是 a 的实例child。
parent p允许对 to 进行赋值,因为每个child对象也是一个parent对象。
将对象分配child给具有其父级类型的变量使您能够对类的接口进行编程,从而将类的使用限制child为其父级的方法。这使您可以灵活地稍后更改实施:
Parent p = new OtherChild();
Run Code Online (Sandbox Code Playgroud)
这样,使用的代码p不需要知道它正在访问Child或OtherChild对象。
| 归档时间: |
|
| 查看次数: |
5678 次 |
| 最近记录: |