本文主要包括以下内容:
1.继承
2.方法重写/重载
3.final关键字
4.多态
5.抽象类
6.接口
继承
- 1.格式:
-
class 子类名 extends 父类名 { 本类构造器; 新增数据成员; 新增的方法; }
- 2.类继承
- Java中,无法继承private成员[方法、数据] (但是可以通过公有set|get方法,操作private成员)
- Java中,无法继承 构造器
- Java中,子类 必须 自定义 本类构造器
- 3.
super();
- 调用父类的无参构造器,进行 父类部分初始化
- 如果用户不指定,系统会默认加上
- super如果自己写,必须在第一句
- 4.继承初始化步骤
- 先调用父类初始化
- 再初始化本类
- 5.继承的好处
- 提高了代码的复用性
- 提高了代码的维护性
- 让类与类之间产生了关系,是多态的前提
- 继承的弊端
- 类的耦合性增强了
- 6.Java只支持单继承,不支持多继承(一个儿子只能有一个老爸)
- 7.Java支持多层继承(子类孙类无穷也)
- 只关心父类和当前类即可
- 8.子类中三种方法调用父类属性/方法(父属方 | this.父属方 | super.父属方)
- 9.this关键字
- 类的成员方法
- 构造方法
- this(实参);
- this.数据成员;
- this.成员函数();
- 普通成员方法
- this.数据成员;
- this.成员函数();
- static 方法不可以使用this
- 构造方法
- 类的成员方法
- 10.super关键字
- 构造方法
- 调用父类构造方法初始化
- 调用父类成员属性
- 调用父类成员方法
- 构造方法
- 11.实例化子类对象
- 1.static父类
- 2.static子类
- 3.父类构造代码块
- 4.父类构造方法
- 5.子类构造代码块
- 6.子类构造方法
- 12.子类的实例化对象不能调用父类的已被重写的旧方法
- 但是可以在子类中通过
super.旧方法();
调用
- 但是可以在子类中通过
方法重写
- 1.类的继承层级结构中,子类中定义 父类相同形式 的函数,则构成重写
- ★函数名一样,形参列表一样,返回值也一样
- 权限不能变小(public之类的)
- 异常不能变大(也不能变多)
- 2.父类中的私有方法不能被重写
- 我们根本没法继承到父类私有方法,重写以后没有任何意义
- 3.父类静态方法,子类必须通过静态方法进行重写
- 结论:子类进行方法重写时,最好声明一致
- 4.重写方法,对从父类继承的方法,会产生覆盖
父类 引用 = new 子类();
- 这个引用所指向的空间中,子类方法区的内容不可访问,重写的方法覆盖了在父类的方法区的旧方法
- 子类方法中,this表 当前函数的调用对象
- 子类方法中,super表 当前对象父类部分
- 结论:子类进行方法重写时,最好声明一致
方法重载
- 一个类中,方法名相同,形参列表不同,对于返回值类型,修饰符都没有要求
final关键字
- 1.final修饰类,则类不能被继承
- 2.final修饰变量,则变量就成了常量,初始化以后值不能改变
- 默认初始化值,不算数
public final int num;
× - 或先定义不赋值,再去构造器中初始化
- 或先定义不赋值,再去构造代码块中初始化
- 或由用户主动初始化
public final int num = 10;
√ - 总结:对象构造完成前对final进行一次初始化即可。
- ps:常量命名规则,若一个单词则全大写,多个单词则下划线连接全大写
- 默认初始化值,不算数
- 3.final修饰方法,则方法不能被重写
- 4.final修饰局部变量,则此变量不在栈空间,而在常量区开辟内存
- 5.final修饰 引用数据类型 局部变量
final Father f = new Father();
√f.setNum(10);
√×f = new Father();
- 总结:final修饰的引用变量,其值不能修改,但是其指向堆空间 里面的数据是可以修改的
多态
- 1.概述:一种事物,多种形态
- 2.前提:
- 要有继承关系
- 要有方法重写
- 父类引用指向子类对象
- 父类引用 调用 重写方法
- ↑此时
父类引用.被重写的方法
,调用的是子类重写的方法 - 父类引用不能调用子类新增的方法
- 3.好处:【扩展性 健壮性 灵活性】
- 父子类继承层次结构
- 子类中重写方法
- 父类引用 指向 子类对象
- 父类引用 调用 重写方法
父子类赋值转换
-
1.向上转型(隐式转型)
父类 引用 = new 子类();
√- 子类是小范围,父类是大范围,相当于int的数可以给double类型赋值
-
2.向下转型(显式转型)
if(父类对象 instanceof 子类){ 子类 引用 = (子类)父类对象; }
- 子类引用指向父类对象
- 有个前提,父类对象本身就是子类类型(先经过了向上转型)
- 把向上转型的东西,再转回来,才能向下转型
抽象类
- 用abstract修饰的类,一般作为父类使用
- 抽象类不能实例化,但是可以用来指向子类对象,子类是正常类
- 抽象就是不去实现 不确定的方法 或 功能,而只声明出来这些方法
- 具体的实现让子类根据实际需要去重写完成(如Shape类的求面积方法,让子类Circle和Triangle自己重写)
- 抽象类的定义格式:(与正常类别无二致)
-
abstract class 类名{ √数据成员 √构造方法 √普通成员方法|抽象方法 √内部类|枚举类型 }
- 抽象类 不一定要有抽象方法
- 包含抽象方法的类,一定是抽象类或接口
- 抽象方法没有 函数体,如:
public abstract void 方法名();
(没有 花括弧) - 抽象方法不能用private修饰(是给人重写的)
- 抽象方法必须重写出来
- 其中,构造方法用来让子类
super();
调用 - 总结:有得有失
- 得到包含抽象方法的能力
- 失去直接实例化对象的能力
接口
-
1.接口是对Java单继承的补充,接口不是类
interface 接口名{ public static final 成员; public abstract 返回值 方法(); }
-
2.若在接口中定义
int num = 10
;- 系统默认修饰符为
public static final int num = 10;
[建议手写出来] - 接口没有构造器,也不需要初始化
- 接口不可以实例化对象,只能 定义引用 指向 实现类对象
接口名 引用 = new 实现类();
- 系统默认修饰符为
-
3.定义 接口 的 实现类
class 类名 implements 接口名 { 重写接口的所有抽象方法; }
- 可能是正常类【重写所有抽象方法】
- 可能是抽象类【有抽象方法未重写】
-
4.除此外和继承了一个父类别无二致,继承的父类的亲爸,接口是干爹,都是爸
-
5.一个类可以同时实现多个接口,多实现
implements 接口1,接口2,接口3...
-
6.接口和接口之间存在继承关系,并且可以是多继承
interface SonInter extends FatherInter1,FatherInter2...{}
-
7.接口最关键的作用是 打破了单继承的局限性
-
8.接口和类设计理念的区别
- 抽象类 被继承体现的是“is a”的关系,抽象类定义的是该继承体系的共性功能
- 接口 被实现体现的是“like a”的关系,接口中定义的是该继承体系的扩展功能