面向对象
继承 extends
class Animal {
public void sleep () {
System.out.println("睡觉");
}
public void eat () {
System.out.println("吃饭");
}
}
class Cat extends Animal {}
class Dog extends Animal {}
Cat c1 = new Cat();
c1.eat();
c1.sleep();
Dog d1 = new Dog();
d1.eat();
d1.sleep();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
TIP
- Java 中类 继承的特点
- java 只支持单继承. 不支持多继承
- java 支持多层继承
- 继承的注意事项
- 子类只能继承父类所有非私有的 成员
- 子类不能继承父类的 构造方法, 但是可以通过super 关键字 访问父类构造方法
- 不要为了部分功能而去继承
如果想用这个类所有的功能, 应该看 最底层类创建的对象
如果想看这个类共有的特性, 应该看 最顶层的类
class DemoA {
public void show (){
System.out.println("demoA");
}
}
class DemoB {
public void show (){
System.out.println("demoB");
}
}
class DemoC extends DemoA, DemoB{ // ✘
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
继承中变量的关系
子父类 出现同名变量
就近原则 子类有 就不用父类的
class Animal {
int a = 1;
int b = 2;
}
class Cat extends Animal {
int a = 3;
int c = 4;
public void print () {
System.out.println(a+"..."+b+"..."+c); // 3...2...4
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
this与super
- this super 代表什么
- this 代表当前对象的引用, 谁调用我, 我就代表谁
- super 代表当前对象父类的引用
- 使用区别
- 调用成员变量
- this.成员变量 调用本类的成员变量, 也可以调用父类的成员变量
- super.成员变量 调用父类的成员变量
- 构造方法
- this(...) 调用本类的构造方法
- spuer(...) 调用父类的构造方法
- 调用成员方法
- this.成员方法 可调用本类成员方法 也可调父类
- spuer.成员方法 调父类成员方法
- 调用成员变量
继承中构造方法的关系
注意
子类中所有的构造方法默认都会访问父类中空参构造方法
因为子类会继承父类的数据, 可能还会使用父类的数据 . 所以 子类初始化之前, 一定要先完成父类数据的初始化
public class Demo5_Extends {
public static void main(String[] args) {
Son s1 = new Son();
}
}
class Father {
int a = 1;
public Father (){
System.out.println("Father 的构造方法");
}
}
class Son extends Father {
public Son () {
super(); // 这是一条语句 如果不写 系统会默认加上 用来访问父类的空参构造
System.out.println(super.a);
System.out.println("son 的构造");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
TIP
class Father extends Object {}
- 每一个构造方法的第一条语句默认super(); Object 类是最顶层的
父类没有 无参构造方法
子类中所有的构造方法默认都会访问父类中空参构造方法
class Father {
private String name;
private int age;
public Father(String name, int age){
this.name = name;
this.age = age;
System.out.println("Fathe有参构造");
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
定义子类 继承
class Son extends Father {
public Son (){
super("王五", 32); // 使用super 关键字 调用父类构造方法, 加上参数就是 父类有参 构造方法
// this("野猪", 12); // this 调用本类 构造
System.out.println("son 空参构造");
}
public Son (String name, int age){
super(name, age);
System.out.println("son 有参构造");
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
面试题
class Fu {
public int num = 10;
public Fu (){
System.out.println("FU");
}
}
class Zi extends Fu{
public int num = 20;
public Zi (){
System.out.println("zi");
}
public void show() {
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
public class Demo6_Test {
public static void main(String[] args) {
Zi z1 = new Zi();
z1.show();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- 主方法 new zi
- 进入 zi 的无参构造, 然后super 初始化父类 无参构造 打印出
FU
- super 关键字执行完 执行子类无参构造 打印出
zi
- 执行show方法
- show方法 声明方法内的num,
- 输出 方法内的num 30, this本类的num 20, super父类的10
`FU ZI 30 20 10
方法重写
- 父类私有方法不能被重写
- 因为父类私有方法无法被继承
- 子类重写父类方法时,访问权限不能更低
- 最好一致
- 父类静态方法, 子类也必须通过静态方法重写
- 子类重写父类方法时最好声明一样
finnal 概述
- final修饰类, 类不能被继承
- 修饰变量, 变量就变成常量, 只能被赋值一次
- 修饰方法, 方法不能被重写
抽象类
抽象类和抽象方法必须用 abstract 修饰
- abstract class 类名 {};
- public abstract void 方法名 ();
抽象类不一定有抽象方法, 有抽象方法的类一定是抽象类 或者接口;
- 如果抽象类是可以实例化的, 意味着可以调用抽象方法,而抽象方法没有具体的实现 调用是没有意义的
抽象类不能实例化
- 按照多态的方式 有子类去实例化 这也是多态的一种, 抽象类多态
抽象类的子类
- 要么是抽象类
- 要么重写抽象类中 所有的 抽象方法