1.继承的入门
要点
1. 继承的由来?(为什么要继承?)
共性抽取,代码重用
多个类有重复的代码,可以将重复的代码抽取到一个独立的类中,让其他类与独立类产生一个关系
这样,其他类就可以使用独立类中的内容了,这个独立的类我们称为父类,其他类称为子类;这个关系就是继承.
2. 继承的格式,称谓
class Fu {...} //父类,超类,基类
class Zi extends Fu { //写子类特有 } //子类,派生类
3. 写继承的步骤
1.先写父类, publc class Person { public void work() {} }
2.再写子类继承父类
public class Student extends Person {}
public class Teacher extends Person {}
3.在测试类中,创建子类对象,调用方法
2.继承的好处和弊端
继承的好处和弊端是?
好处:
1. 提高复用性
2. 提高可维护性(方便修改)
3. 继承让类与类之间有了层次关系,是多态的前提条件
弊端:
类与类的耦合性增强了(类之间有了牵连,父类修改有可能影响子类)
降低了子类的灵活性(父类非私有的东西,子类不想要都不行! )
软件设计的一项原则: 高内聚,低耦合
高内聚: 内聚指的是实现功能的能力,高内聚是指实现功能的能力越强越好,一个类应该只包含单一的职责,并且该职责被完整地封装在这个类中。
低耦合: 类与类之间的关联越少越好. 关联太多,导致维护困难.
( controller 调用 service ,service调用dao, dao如果修改了,只会影响service,不会影响controller和其他类,如果谁都可以调用dao,要是dao要修改,那么相关的类都要修改,很麻烦!!)
什么时候适合使用继承
1.存在重复代码
2.符合 is a 的关系
例如: 老师 是 人类 的一种
小轿车 是 汽车的一种
客运飞机 继承 飞机
战斗机 继承 飞机
反例:
飞机可以飞行
鸟也可以飞行
鸟 继承 飞机 ? 合适吗?
3.继承的特点
java中继承的特点
- Java中类只支持单继承,不支持多继承
- 错误范例:class A extends B, C { }
- Java中类支持多层继承
- 多层继承示例代码:
//爷爷类
class YeYe {
public void walk() {
System.out.println("爷爷爱散步");
}
}
//父类
class Fu extends YeYe {
public void read() {
System.out.println("读书");
}
}
//干爹
class GanDie {
}
//子类
class Zi extends Fu {
}
4.继承中成员变量访问特点
要点:
public class Demo1 {
public static void main(String[] args) {
Zi z = new Zi();
z.method();
}
}
class Fu {
int age = 40;
}
class Zi extends Fu {
int age = 18;
public void method() {
System.out.println(age); //在子类成员范围找age = 18
}
}
小结:
在子类方法中访问一个变量,就近原则
可以使用 this,super区分
另外:
- 如果方法定义在父类中,则优先使用父类的成员变量
- 如果方法定义在子类中,则优先使用子类的成员变量
5.this和super访问成员的格式
6.继承中成员方法的访问特点
通过子类对象访问一个方法,可以从两方面入手:
1.子类成员范围找
2.父类成员范围找
继承后,子父类之间成员方法的关系
1.就近原则
2.子父类成员变量同名的,
this.子类成员方法(),super.父类成员()
7.方法重写概述和应用场景
方法重写概述
- 在继承体系中,子类出现了和父类中一模一样的方法声明
方法重写的应用场景
- 当子类需要父类的功能,而功能主体子类有自己特有的内容
- 可以重写父类中的方法,这样,既沿用了父类的功能,又定义了子类特有的内容
方法重载(Overload)和重写(Override)的区别?重载的方法能否根据返回类型进行区分?
-
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
-
重载:发生在同一个类中,方法名相同参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关,即重载的方法不能根据返回类型进行区分。
-
重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类(里氏代换原则);如果父类方法访问修饰符为private,则子类中就能够是重写。
8.方法重写的注意事项
方法重写注意事项
- 父类中私有方法不能被重写
- 父类静态方法,子类必须通过静态方法进行重写,父类非静态方法,子类也必须通过非静态方法进行重写
- 注意:静态方法不能被重写!如果在子类中,也存在一个方法声明一模一样的方法,可以理解为,子类将父类中同名的方法,隐藏了起来,并非是方法重写!
- 子类重写父类方法时,访问权限必须大于等于父类
要点:
- 父类 private 修饰的成员,子类不能直接访问
- 子类重写父类方法,仅限修饰符;访问权限范围可以更大,但不能更小
9.权限修饰符
要点:
1. 默认(啥也不写): 包权限 (同一包下的任何类可以使用)
2. protected(保护): 包类 + 子类 (同一包下的任何类和其他包的子类可用)
10.继承中构造方法的访问特点
总结:
继承中构造方法的执行特点:
子类构造一定会先调用父类构造(先构造父后构造子)
子类构造调用父类构造的方式:
- 默认情况下,子类构造调用父类空参构造
子类每个构造第一行什么也不写,会默认有一句 super(); - 如果父类只有带参构造,没有空参构造,子类构造如何访问?
super(参数列表); //调用父类构造方法初始化从父类继承的成员变量
11.继承中构造方法相关要点
继承中构造方法的执行特点:
子类构造一定会先调用父类构造(先构造父类后构造子类)
子类构造调用父类构造的3种方式:
1.默认情况下,子类构造调用父类空参构造
子类每个构造第一行什么也不写,会默认有一句super();
super();
2.子类构造第一行,可以通过super(参数列表)调用父类的带参构造
super(参数列表);
3.子类构造第一行,可以通过this(参数列表)调用本类其他构造,让其他构造调用父类构造.
this(参数列表);
注意:
3种方式一定有一种
3种方式只能有一种
this(参数列表) 和 super(参数列表)语句只能出现在构造方法中,并且必须是构造方法第一条有效语句;并且二者不能共存。