1.在Java中,所有的继承都是公共继承,而没有c++中的私有继承和保护继承
通过扩展超类定义子类时,只需要指出子类和超类的不同之处。因此在设计类的时候,应该将最一般的方法放在超类中,而将特殊的方法放在子类中。
2.超类的私有字段
超类的私有字段不可以直接访问,需要使用super.getField()来获取
3.this和super
有些人认为super与this引用是类似的概念,实际上这样比较并不恰当。super并不是一个对象的引用。例如,不可以将值super赋给另外一个变量,它只是指示编译器调用超类方法的特殊字段。
this有两个含义
- 指示隐式参数(即方法的调用者)的引用
- 调用该类的其他构造器
super也有两个含义
- 调用超类的方法
- 调用超类的构造器
使用super构造器必须是子类构造器的第一条语句。如果子类构造器没有使用super显式的调用超类的构造器,编译器就会默认地调用超类的无参构造器。如果超类没有无参构造器,而子类也没有调用超类的构造器,编译器就会报错。super()和this()都必须是构造器的第一行,意味着一个构造器不能同时调用super()和this()
4. 多态
多态 :一个对象变量可以指示多种实际类型的现象称为多态。
动态绑定:在运行时能够根据对象实际类型自动地选择调用适当的方法,称为动态绑定。
对象变量是多态的,一个Employee类型的变量可以指向Employee类型的变量,也可以指向Employee类的任何一个子类的对象。
5.理解方法调用
1.编译器查看对象的声明类型和方法名。
2.编译器确定方法调用中提供的参数类型。
3.如果是private方法,static方法、final方法或者构造器,那么编译器将可以准确的知道应该调用那个方法。这是静态绑定。
4.程序运行并且采用动态绑定调用方法时虚拟机必须调用与x所引用的对象实际类型相对应的那个方法,
在覆盖一个方法时,子类方法不能低于超类方法的可见性。
6.强制类型转换
1.子类转换为超类时,不需要进行强制类型转换。
2.将一个超类的引用赋给一个子类变量时,必须使用强制类型转换,才能通过运行时的检查。如果试图在继承链上进行向下的强制类型转换,并且“谎报”对象包含的内容,会产生一个ClassCastException异常。
建议这样使用强制类型转换
if(staff[0] instanceof Manager){
boss = (Manager) staff[0];
}
//对象为null时,运算结果为false
综上:
1.只能在继承层次内进行强制类型转换。
2.将超类强制转换成子类之前,应该使用instanceof进行检查
#一般只有在需要使用子类特有的方法时才需要强制类型转换。只要没有捕获ClassCastException异常,程序就会终止执行。一般情况下,最好尽量少用强制类型转换和instanceof运算符。
7.抽象类
1.为了提高程序的清晰度,包含抽象方法的类本身必须被声明为抽象类。
2.除了抽象方法之外,抽象类可以包含字段和具体方法。
3.抽象类不能被实例化。
public abstract class Person {
private String name;
public Person(String name){
this.name = name;
}
public abstract String getDescription();
public String getName(){
return name;
}
}
public class Student extends Person {
private String major;
public Student(String name,String major){
super(name);
this.major = major;
}
@Override
public String getDescription() {
return "A student named "+ super.getName()+" who major in " + major;
}
}
8.访问控制修饰符
1.仅对本类可见——private
2.对外部全部可见——public
3.对本包和所有子类可见——protected
4.对本包可见——默认,不需要修饰符