1.继承比较好理解,多各类有相同的属性和行为的时候,将这些内容抽取到一个单独的类中就可以简化成继承关系了
1)表达式:class 子类名 extends 父类名 {}
2)好处:a.提高了代码的复用性,b.提高了代码的维护性,c.让类与类产生关系,是多态的前提。
3)Java只支持单继承,不支持多继承,但可以多层继承。
4)子类只能继承所有父类的非私有成员,不能继承父类的构造方法,但是可以通过super关键字去访问父类的构造方法。
5)继承中成员变量的关系:
当子类中的成员变量和父类中的成员变量名称一样时,在子类方法中访问一个变量的查找顺序:
a:在子类方法的局部范围找,有就使用
b:在子类的成员范围找,有就使用
c:在父类的成员范围找,有就使用(肯定不能访问到父类局部范围)
d:如果还找不到,就报错。
2.this和super的区别?
this代表本类对应的引用。
super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员)
用法上
1)调用成员变量
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
2)调用构造方法
this(...) 调用本类的构造方法
super(...) 调用父类的构造方法
3)调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法
注意:super(…)或者this(….)必须出现在第一条语句上,否则,就会有父类数据的多次初始化
3.继承中构造方法的关系
子类中所有的构造方法默认都会访问父类中空参数的构造方法
因为子类会继承父类中的数据,可能还会使用父类的数据。
所以,子类初始化之前,一定要先完成父类数据的初始化。
注意:子类每一个构造方法的第一条语句默认都是:super();
4.执行流程,判断结果
class Fu {
static {
System.out.println("静态代码块Fu");
}
{
System.out.println("构造代码块Fu");
}
public Fu() {
System.out.println("构造方法Fu");
}
}
class Zi extends Fu {
static {
System.out.println("静态代码块Zi");
}
{
System.out.println("构造代码块Zi");
}
public Zi() {
System.out.println("构造方法Zi");
}
}
class ExtendsTest2 {
public static void main(String[] args) {
Zi z = new Zi();
}
}
执行结果是:
静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi
1)一个类的静态代码块,构造代码块,构造方法的执行流程
静态代码块 > 构造代码块 > 构造方法
2)静态的内容是随着类的加载而加载
静态代码块的内容会优先执行
3)子类初始化之前先会进行父类的初始化
5.方法重写
子类中出现了和父类中一模一样的方法声明,也被称为方法覆盖,方法复写。
6.方法重写的注意事项
1)父类中私有方法不能被重写
2)子类重写父类方法时,访问权限不能更低
3)父类静态方法,子类也必须通过静态方法进行重写。(其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解)
7.方法重载能改变返回值类型吗?
方法重载能改变返回值类型,因为它和返回值类型无关。
Override:方法重写
Overload:方法重载
8.final关键字是最终的意思,可以修饰类,成员变量,成员方法。
特点:
1)final可以修饰类,该类不能被继承。
2)final可以修饰方法,该方法不能被重写。(覆盖,复写)
3)final可以修饰变量,该变量不能被重新赋值。因为这个变量其实常量。
自定义常量 final int x = 10;
9.final修饰局部变量
1) 在方法内部,该变量不可以被改变
2) 在方法声明上:
基本类型,是值不能被改变
引用类型,是地址值不能被改变
10.多态
某一个事物,在不同时刻表现出来的不同状态。
多态前提和体现
1)有继承关系
2) 有方法重写
3) 有父类引用指向子类对象
11.多态中的成员访问特点:
1)成员变量
编译看左边,运行看左边。
2)构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
3)成员方法
编译看左边,运行看右边。
由于成员方法存在方法重写,所以它运行看右边。
4)静态方法
编译看左边,运行看左边。
(静态和类相关,算不上重写,所以,访问还是左边的)
12.多态的好处
1)提高了程序的维护性(由继承保证)
2)提高了程序的扩展性(由多态保证)
13.多态的弊端: 不能使用子类的特有功能。
所以为了引用子类的特有功能,把父类的引用强制转换为子类的引用
对象间的转型问题:
向上转型:
Fu f = new Zi();
向下转型:
Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。
14.自己在默写代码时出现的错误
/*
多态练习:猫狗案例
*/
class Animal
{
public void eat(){
System.out.println("进食");
}
}
class Cat extends Animal
{
public void eat(){
System.out.println("吃鱼<?)))><<");
}
public void playGame(){
System.out.println("玩毛线,抓蝴蝶");
}
}
class Dog extends Animal
{
public void eat(){
System.out.println("吃骨头@==@");
}
public void lookDoor(){
System.out.println("有人来了,汪汪~~");
}
}
class PolymorphismTest // polymorphism:多态性
{
public static void main(String[] args){ /*第一次编译又忘了打这一句,看来以后防止自己再忘,写代码是首先写主方法*/
Animal a = new Cat();
a.eat();
Cat b = (Cat)a;
b.eat();
b.playGame(); /*a.playGame();// 错误:变量a的类型为Animal*/
System.out.println("---------------");
a = new Dog();
a.eat();
Dog c = (Dog)a;
c.eat();
c.lookDoor();
}
}