面向对象之 继承&抽象
0x01、继承
2、 继承的含义
继承:在java中指的是“一个类”可以“继承自”“另一个类”。 "被继承的类"叫做: 父类/超类/基类,"继承其他类的类"叫做:子类。继承后,“子类”中就“拥有”了“父类”中所有的成员(成员变量、成员方法)。 “子类就不需要再定义了”。
3、继承的好处
- 提高代码的复用性(减少代码冗余,相同代码重复利用)。
- 使类与类之间产生了关系。
4、继承语句格式
class 父类{
...
}
class 子类 extends 父类{
...
}
如果子类和父类出现不重名的成员变量,这时候访问是没有任何影响的。
父类代码:
public class Fu {
int num = 10;
}
子类代码:
int num2 = 6;
public void show(){
System.out.println("父类成员变量"+num);
System.out.println("子类成员变量:"+num2);
}
main代码:
public static void main(String[] args) {
Zi zi = new Zi();
zi.show();
}
5、继承后成员访问规则
- 构造方法不能被继承
- 父类的“私有成员”可以被子类继承,但子类不能被直接访问。
- 当通过“子类”访问非私有成员时,先在子类中找,如果找到就使用子类的,找不到就继续去“父类”中找。
6、方法重写
但是在编写代码中,难免会有一些变量重名那么这时候去访问的时候就会有影响
方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。
class Fu{
public void method(){
System.out.println("Fu method方法");
}
// 重写使用场景
public void sport(){
System.out.println("运动的方式为游泳");
}
public void run(){
System.out.println("第1圈");
System.out.println("第2圈");
System.out.println("第3圈");
System.out.println("第4圈");
}
}
class Zi extends Fu{
@Override
public void method(){
System.out.println("Zi method方法");
}
@Override
public void sport() {
System.out.println("运动的方式为跑步");
}
@Override
public void run() {
// 调用父类的方法来执行一下
super.run();// 调用父类的run方法
System.out.println("第5圈");
System.out.println("第6圈");
System.out.println("第7圈");
}
}
public class Test {
public static void main(String[] args) {
Zi zi = new Zi();
zi.sport();
zi.run();
}
}
(1)、重写注意事项
-
方法重写是发生在子父类之间的关系。
-
子类方法重写父类方法,返回值类型、方法名和参数列表都要一模一样。
-
子类方法重写父类方法,必须要保证权限大于等于父类权限。
- 访问权限从大到小: public protected (默认) private
-
使用@Override注解,检验是否重写成功,重写注解校验!
- 建议重写方法都加上这个注解,一方面可以提高代码的可读性,一方面可以防止重写出错!
7、this和super关键字
但是在编写代码中,难免会有一些变量重名那么这时候去访问的时候就会有影响。如果重名的话优先显示的是子类的成员变量,那么这个时候我们就会使用到this和super这2个关键字。
(1)、this和super关键字的介绍
- this:存储的“当前对象”的引用;
- this可以访问:本类的成员属性、成员方法、构造方法;
- super:存储的“父类对象”的引用;
- super可以访问:父类的成员属性、成员方法、构造方法;
(2)、this关键字的三种用法
this访问本类成员变量: this.成员变量
public class Student{
String name = "张三";
public void show(){
String name = "李四";
System.out.println("name = " + name);// 李四
System.out.println("name = " + this.name);// 张三
}
}
this访问本类成员方法: this.成员方法名();
public class Student{
public void show(){
System.out.println("show方法...");
this.eat();
}
this访问本类构造方法: this()可以在本类的一个构造方法中,调用另一个构造方法
public class Student{
public Student(){
System.out.println("空参构造方法...");
}
public Student(String name) {
this();//当使用this()调用另一个构造方法时,此代码必须是此构造方法的第一句有效代码。
System.out.println("有参构造方法...");
}
}
(3)、super关键字的三种用法
super访问父类的成员变量: super.父类成员变量名
super访问父类的成员方法: super.成员方法名();
super访问父类的构造方法: super()
super的注意事项:
1、super访问成员变量和成员方法: 优先去父类中找,如果有就直接使用,如果没有就去爷爷类中找,如果有,就用,依次类推...
2、子类的构造方法默认会调用父类的空参构造方法,如果父类中的没有空参构造方法,只定义了有参构造方法,会编译报错
8、继承的特点
- Java只支持单继承,不支持多继承。
// 一个类只能有一个父类,不可以有多个父类。
class A {
}
class B {
}
class C1 extends A {// ok
}
class C2 extends A, B {// error
}
- 一个类只能有一个父类,但可以有多个子类。
// A可以有多个子类
class A {
}
class C1 extends A {
}
class C2 extends A {
}
- 可以多层继承。
class A /*extends Object*/{// 爷爷 默认继承Object类
}
class B extends A {// 父亲
}
class C extends B {// 儿子
}
补充: 顶层父类是Object类。所有的类默认继承Object,作为父类。
class A {} 默认继承Object类
class B extends A{} B的父类就是A,但是A的父类是Object类
0x02、抽象类
抽象方法 : 没有方法体的方法。
修饰符 abstract class 类名{
}
抽象类:包含抽象方法的类。
修饰符 abstract 返回值类型 方法名(形参列表);
例如:
public abstract void work();
(1)、抽象类的特点
- 抽象类不能被创建对象,就是用来做“父类”,被子类继承的。
- 抽象类不能被创建对象,但可以有“构造方法”——为成员属性初始化。
- 抽象类中可以没有抽象方法,但抽象方法必须定义在抽象类中
- 子类继承抽象类后,必须重写抽象类中所有的抽象方法,否则子类必须也是一个抽象类