一、继承(Java不支持多继承)
1.继承的语法
public class Animal{
String name;
int age;
public void eat(){
System.out.println(name+"正在吃饭");
}
}
public class Dog extends Animal{
void bark(){
System.out.println(name+"汪汪汪");
}
}
public static void main(String[] args){
Dog dog=new Dog();
dog.eat();
dog.bark();
}
(1)子类会继承父类中的成员变量或成员方法
(2)子类继承父类后,要添加自己特有的成员
2.子类成员访问父类
(1)如果访问的成员变量(方法)子类中有,优先访问自己的
(2)如果访问的成员变量(方法)子类中无,访问父类的
(3)如果成员变量(方法)同名,优先访问自己的
(4)通过派生类访问父类与子类同名方法时,父与子的参数列表不同时,根据传递的参数选择合适的访问;父与子是重写时,只能访问子类,无法访问父类
3.super关键字(只能是直接的父类,不能再往上的父类)
super.成员变量
super.成员方法
super()访问父类构造方法
(1)作用
在子类访问父类的成员变量和方法(只能在非静态方法中使用)
必须是构造方法中的第一句
(2)与this的区别
a.this是对当前对象的引用,super是子类对象中从父类继承下来部分成员的引用
b.非静态方法中,this访问本类方法的属性和方法;super访问父类继承下来的
c.this是非静态成员方法的一个隐藏参数,而super不是
d.成员方法直接访问本类成员,编译后会将this还原;super编译之后在字解码层面不存在
e.this用于调用本类构造方法,super用于调用父类构造方法,不能同时存在
f.构造方法中一定存在super,不写也会增加;this不写就没有
4.初始化顺序
(1)静态域(静态代码块与静态成员变量,谁在前谁先初始)>实例代码块>构造方法块
(2)静态代码块只执行一次,有对象创建才会执行实例代码块
(3)父类静态代码块先于子类的静态代码块,且最先
(4)父类实例和构造紧接着执行
(5)子类实例和构造紧接着执行
5.final关键字
(1)修饰变量:不能被修改
(2)修饰类:不能被继承
(3)修饰方法:不能被重写
6.继承与组合
继承:对象间是is-a关系
组合:对象间是has-a关系(extend)
class Engine{
#...
}
class Tire{
#...
}
class Car{
private Tire tire;
private Engine engine;
#...
}
class Benz extend Car{
#...
}
二、多态
同一件事发生在不同对象身上,会产生不同的结果
eg:eat这个方法,狗吃狗粮,猫吃猫粮
1.实现条件
(1)必须在继承体系下
(2)子类必须对父类中的方法重写
(3)通过父类引用子类重写的方法
class Animal{
String name;
public Animal(String name){
this.name=name;
}
public void eat(){
System.out.print(name+"吃饭");
}
}
public class Cat extends Animal{
public Cat(String name){
super(name);
}
@Override
public void eat(){
System.out.print(name+"吃鱼");
}
}
public class Dog extends Animal{
public Dog(String name){
super(name);
}
@Override
public void eat(){
System.out.print(name+"吃骨头");
}
}
public class Test{
public static void eat(Animal a){
a.eat();
}
public static void main (String[] args){
Cat cat=new Cat("蛋黄");
Dog dog=new Dog("蛋挞");
eat(cat);
eat(dog);
}
}
2.重写
(1)函数名相同
(2)形参不变,返回值类型可以不同(但必须具有父子关系)
(3)访问权限不能比父类低(父类public,子类就不能写protected)
(4)父类用static、private、final修饰的方法和构造方法不能重写
静态绑定:根据传递类型确定具体调用哪个方法
动态绑定:多态的基础,不确定方法的行为,等程序运行时才确定具体的那个类的方法
3.向上转型
(1)语法
父类类型 对象名=new 子类类型
class A{ }
class B extends A{ }
class C extends B{ }
#以下都可以通过
A b=new B();
A c=new C();
(2)使用
#a.子类对象直接赋值给父类对象
Animal cat=new Cat("蛋黄")
#b.方法传参:形参为父类引用
public static void eat(Animal a){
a.eat();
}
#c.做返回值,返回子类对象
public static Animal buy(String n){
if("狗"==n){
return new Dog("狗狗");
}else if("猫"==n){
return new Dog("猫猫");
}else{
return null;
}
}
(3)缺点
不能调用子类特有的方法
4.向下转型
不安全eg:本来是猫,向下转型成猫则是安全的;本来是猫,向下转型成狗,则不安全
Cat cat=new Cat("蛋黄");
if(animal instanceof Cat){
cat (Cat)animal;
}
5.多态优缺点
优(1)避免大量用if-else
(2)可扩展能力强
缺(3)运行效率低