一、子类可以继承父类所有可以访问的数据域和方法(也就是除了private)
1)数据和方法的可见性
2)使用可见性修饰符控制如何访问数据和方法
3)子类不能继承私有数据域,但是可以通过修改器、访问器调用(例如setColor(color);和getColor())
4)子类必须调用父类的构造方法(显式or隐式)
4.1)如何调用? super()或super(parameters);
这两句必须出现在构造方法的第一行(不意味着是第一个构造方法的第一行);
this()也必须出现在本类构造方法的第一行
不写的情况下,默认super();有this(),无super()
4.2)构造方法链
当构造一个子类对象时,子类构造方法会在完成自己的任务前,首先调用它的父类的构造方法
例子:
输出结果:
(1)Performs Person's tasks
(2).....(不想写)
(3)....
(4)....
4.3)若父类没有无参构造
public class Apple extends Fruit{
}
public class Fruit{
public Fruit(String name){
System.out.println("AAAA");
}
}
这里编译会出错。原因是Apple默认调用super()也就是Fruit的无参构造,而Fruit有有参构造,就不会有自动的默认无参构造。。。。要想编译通过,可以在Fruit类加上无参构造方法
4.4)调用父类中的方法
super.方法名(参数);
4.5)方法重写
4.5.1)要求:子类中重写的方法,必须和父类中的方法名字、参数相同;返回值相同或者子类;子类的修饰符>=父类;抛出异常相同或者子类
4.5.2)仅当实例方法可访问时,才能被覆盖。。什么叫可访问,看上面2)的那张图。。。如果不能访问,那这两个方法没有重写关系
4.5.3)静态方法也能被继承,但是不能被覆盖,只能叫隐藏。。。这就涉及到多态了
如果A extends B,则B b = new A(); 此时b(对象)可以调用A中的方法。。。这就是多态
静态方法的调用就不是这样了,他是类名.静态方法名。
那如何在子类中调用父类的静态方法呢? 父类名.静态方法名
还不理解的话, 点击 关于静态方法为什么不能被覆盖
4.6)方法重载
4.6.1)要求:方法名相同,参数不同(参数个数、参数类型),返回值无所谓
但是不能出现只有返回值不同,其他都相同的重载
4.6.2)方法重写发生在通过继承而相关的不同类中;方法重载可以发生在同一个类中,也可以发生在由于继承而相关的不同类中
二、多态性
2.1)多态性在类的继承层次上实现;
多态性表现在方法重写
父类的引用可以调用子类的方法
2.2)动态绑定
2.2.1)Object o = new A(); Object是声明类型;A是实际类型
2.2.2)o.toString(); 调用的toString方法,是从实际类型开始找的,没找到就往父类找,还没找到还找父类的父类。。
2.2.3)那声明类型有什么用呢?
对象访问方法,看实际类型;访问变量,看声明类型。
三、对象转换
3.1)隐式转换,例如 Object o = new Student(); 因为Student是Object的子类
3.2)显式转换,例如 Student b = (Student) o; 因为o的实际类型确实是Student。。不然会出错
3.3)instanceof运算符,判断实例是否为类型或者类型子类的实例
Object myObject = new Circle();
if(myObject instanceof Circle){
System.out.println("The circle diameter is " +
((Circle)myObject).getDiameter());
}
注意:对象访问运算符(.)优先于类型转换运算符。所以使用圆括号保证在点运算符之前进行类型转换。
例如上面的 ((Circle)myObject).getDiameter()
3.4)转换基本类型返回一个新的值,而转换一个对象引用不会创建一个新的对象
int age = 45;
byte newAge = (byte)age;//一个新的值赋值给了newAge
Object o = new Circle();
Circle c = (Circle)o;//不会产生新的对象
现在,引用变量o和c都指向同一个对象
四、防止拓展和重写
1)被final修饰的类和方法都不能被拓展(类不能继承;方法不能重写)
public final class A{//该类不能被继承
//....
}
public class Test{
public final void m(){//该方法不能被子类重写
}
}
2)被final修饰的数据域是一个常数
3)静态绑定:在编译期就已经知道调用哪个对象的什么方法
当方法被声明为private, final, static 修饰时,该方法为静态方法,用的是静态绑定
private方法无法被覆盖,那么调用必然是当前类的方法。
final方法同样保证无法被覆盖。
static修饰表明该方法属于某个类,自然是不会产生动态绑定的问题