1.继承:
继承,怎么说呢,就是可以在基类的基础上增加一些属于继承类独有的属性或者方法
1.1格式
//注意java中所有的继承都是公有的
public class Manager extends Employee
{
}
- 关键字:
extends
表明正在构造的新类派生于一个已经存在的类,已经存在的类叫做超类,基类,父类;新派生出来的类叫做子类,派生类,孩子类
1.2注意:
-
继承了除基类构造方法外所有的东西,因此,我们可以将通用的方法放在超类中,而将具有特殊用途的方法放在子类中
-
然而超类中的有些方法对子类并不一定适用,因此就提出了覆盖(override)的概念
-
super与this,super不是一个对象的引用,不能将super赋给另一个对象变量,其实它仅仅就是一个指示编译器调用超类的方法,属性的一个特殊关键字
-
super.属性
super.方法
super()
注意这些都必须放在第一行
如图:
-
-
如果要构造子类,必须先将构造父类
-
基类只能访问自己的方法和属性
-
java是单继承
-
一个类如果被
final
修饰,则 不能被继承 -
对于父类的 private 的属性和方法, 子类中是无法访问的
四种访问权限
- public:类内部和类的调用者都能访问
- private:类的内部可以访问,外部不可以访问
- protected:类内部能访问, 子类和同一个包中的类可以访问, 其他类不能访问
- 默认(包访问):类内部能访问, 同一个包中的类可以访问, 其他类不能访问
图所示:
2.多态:
2.1向上转型:将子类的对象赋给基类的对象(父类引用 引用子类对象)
- 父类只能调用父类自己的方法或者成员属性
- 三种方式:1、直接赋值2、方法传参3、方法返回
发生向上转型时,父类的引用不能调用子类独有的方法
2.2动态绑定
当子类和父类出现相同的方法时
调用某个类的方法, 究竟执行了哪段代码 (是父类方法的代码还是子类方法的代码) , 要看究竟这个引用指向的是父类对象还是子类对象. 这个过程是程序运行时决定的(而不是编译期), 因此称为 动态绑定
2.3方法重写
2.2中子类的方法名和父类的方法名一样,这种我们叫做方法重写(覆盖),即方法名相同,参数列表相同,返回值相同
注意:1.方法不能时private
2.子类的方法权限大于父类的方法权限
3.不能是静态的方法
4.被重写的方法不能被final所修饰
这里再说一下重载
重载和重写不是一个概念:方法名相同,参数列表不同,返回值不做要求
如下图:
发生多态的条件(运行时多态):
1.继承:父类需要引用子类对象
2.通过父类的引用,去调用子类和父类同名的覆盖方法
构造方法内可以发生运行时绑定
public class Animal {
public Animal(){
eat();
}
public void eat(){
System.out.println("Animal::eat()");
}
}
public class Cat extends Animal{
public Cat() {
}
public void eat(){
System.out.println("Cat::eat()");
}
}
public static void main(String[] args) {
Cat cat =new Cat();
cat.eat();//打印两次Cat::eat()
}
反编译一下,我们可以看到对Cat进行对象的创建,调用构造方法,调用子类的构造方法先要调用父类的构造方法,在父类的构造方法内调用了eat方法,而这个方法被子类重写,在运行期发生动态绑定。
2.4向下转型
向下转型的前提是必须进行向上转型
但是我们说向下转型是不安全的,这里我们引入一个instanceof
关键字,A instanceof B表示A是否是B的实例
public static void main(String[] args) {
Animal animal=new Bird();//进行向上转型
animal.eat();
if(animal instanceof Bird){
Bird bird = (Bird) animal;
bird.fly();
}
}