上次我们说到子类可以通过 super 关键字调用父类的构造的方法如果子类没有调用那就默认调用父类默认的构造方法, 可是如果父类没有默认的构造方法怎么办?
父类代码:
- public class Parent {
- public Parent(String name){
- System.out.println("name="+name);
- }
- }
这时子类必须在构造方法中调用父类的构造方法, 不然编译会报错, 并且调用父类构造方法的代码必须写在第一行.
- public class Child extends Parent{
- public Child(String name) {
- super(name);
- }
- }
下面我需要向大家介绍几个名词. 还记的上篇文章的 Animal 类和 Dog 类吗? 其中 Animal 类是父类, Dog 类是子类, 在程序中调用时我们写的是: Dog dog = new Dog("红色"), 这是一点问题都没有的. 但是在 java 中我们还可以这样写: Animal animal = new Dog("红色"). 此时, 我们声明的类型是 Animal 而实际真正的类型是 Dog, 像这样把子类的对象赋值给父类的引用叫做向上转型. 这时使用 animal 变量调用 eat 方法实际调用的子类对象的方法叫做多态, 即一种类型的变量可以引用多种实际类型对象 (取自: java 编程的逻辑). 这时, 对于变量 animal, 它就有两个类型: 类型 Animal 叫做变量 animal 的静态类型; 类型 Dog 叫做 animal 的动态类型, 而 animal.eat() 实际调用的是动态类型的 eat 方法, 称之为方法的动态绑定.
刚才我们解释了什么叫做多态, 什么叫做动态绑定. 那么有动态绑定就应该有静态绑定. 静态绑定在程序的编译期就已经确定. 比如类中的静态变量, 父类中的静态变量和子类中的静态变量即使重名, 使用父类的类名调用的就是父类的静态变量, 使用子类的类名调用的就是子类的静态变量. 这时, 我们可能在想既然把子类对象赋值给父类引用叫做向上转型, 那么如果把子类引用赋值给父类对象是否就是向下转型. 在 java 语法中可以通过强制类型转化实现, 但是并不安全. 例如:
- public static void main(String[] args) {
- Animal animal = new Dog("红色");
- Dog dog = (Dog)animal;
- }
上面的代码没有问题, 因为变量 animal 的动态类型就是 Dog. 可是如果是这样:
- public static void main(String[] args) {
- Animal animal = new Animal();
- Dog dog = (Dog)animal;
- }
变量 animal 的动态类型是 Animal 在 java 编译期不会报错但是在运行期就会抛出类型转化异常. 所以这时我们需要使用关键字 instance 来判断变量 animal 是否是 Dog 类的实例.
java 中的继承(二)
来源: http://www.bubuko.com/infodetail-2974453.html