JAVA 基础 继承与抽象类

2021/4/18 20:25:38

本文主要是介绍JAVA 基础 继承与抽象类,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1 系统优化

2 继承

2.1 继承入门

概述:就是类与类之间的关系(子父类的关系),被继承的类常常将其称之为父类(基类或者超类),而继承父类的类常常将其称之为子类(派生类) 。子类可以直接去使用父类中非私有的成

如何建立继承关系:使用extends关键字

格式:

public class 子类 extends 父类 {}

举例:

public class Student extends Person {}

2.2 好处和弊端

好处:

1、提高了代码的复用性

2、提高了代码的维护性

3、让类与类产生了关系,是多态的前提

弊端:增加了代码之间的耦合性

耦合:类与类之间的关联关系

开发原则:高内聚低耦合

那么我们应该什么时候去使用继承呢? 继承其实体现的是一种关系:“is a”(谁是谁的一种),只要是这种关系,我们就可以去使用继承。

2.3 继承的特点

特点:Java只支持单继承,不支持多继承,但是可以进行多层继承

为什么Java中不支持多继承?为了放置逻辑冲突

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z7KaL32W-1618742814898)(images/image-20210418102304768.png)]

2.4 继承中成员的访问特点

2.4.1 成员变量

特点:变量的访问遵循就近原则

变量的访问查找顺序:

1、在子类的局部位置进行查找

2、在子类的成员位置进行查找

3、在父类的成员位置进行查找

注意:如果子类中出现了和父类同名的成员变量,此时在访问子类的成员变量的时候需要通过this关键字进行显式访问,如果要访问父类中的成员变量就需要通过super关键字进行显式访

问。

示例代码:

Fu类

public class Fu {       // 父类
    int num = 20 ;      // 成员变量num20
}

Zi类

public class Zi extends Fu {       // Zi继承Fu

    int num = 23 ;                 // 成员变量

    public void show(){            // 成员方法
        int num = 30 ;             // 局部变量num
        System.out.println(num);   // 输出变量num
        System.out.println(this.num);	// 访问的Zi中的成员变量num
        System.out.println(super.num);	// 访问的Fu中的成员变量num
    }

}

2.4.2 this和super

this:本类对象的一个引用(通过this可以访问本类中的成员)

super:父类对象的一个引用(通过super可以访问父类中的成员)

this和super在访问成员时对应的格式

类成员this含义super含义
成员变量this.变量名访问本类的成员变量super.变量名访问父类的成员变量
成员方法this.方法名(…)访问本类的成员方法super.方法名(…)访问父类的成员方法
构造方法this(…)访问本类构造方法super(…)访问父类构造方法

2.4.3 成员方法

访问特点:首先会在子类中查找对应的方法,如果有就直接调用;如果没有,从父类中进行查找,如果有就调用,如果没有就报错。

代码实现:

Fu类

public class Fu {

    public void show(){     // 成员方法
        System.out.println("Fu....show...............");
    }

}

Zi类

public class Zi extends Fu {

    public void show(){      // 成员方法
        System.out.println("Zi...............show..............");
    }

    public void method(){    // 成员方法
        this.show();		// 访问本类的show方法
        super.show();		// 访问父类中的show方法
    }

}

测试类

public class ExtendsDemo01 {

    public static void main(String[] args) {

        // 创建子类对象
        Zi zi = new Zi();

        // 调用method方法
        zi.method();

    }

}

2.4.4 方法重写以及应用场景

方法重写:子类中出现了和父类中一模一样的方法声明(返回值类型,方法名和参数列表都相同)这个现象我们将其称之为方法重写,也被称为方法覆盖,方法复写。

方法重载:在一个类中出现了多个同名的方法,但是它们参数列表不同,这中现象就称之为方法重载!

应用场景:当子类需要父类的功能,而功能主体子类有自己特有内容时,那么就可以重写父类中的方法,这样即沿袭了父类的功能,又定义了子类特有的内容。

案例演示:

public class iPearV1 {
    /*
        1. 定义手机类 iPearV1
                    call(String name) : 打电话方法
                    smallBlack() : 语音助手 (speak english...)
     */
    public void call(String name){
        System.out.println("给" + name + "打电话");
    }

    public void smallBlack(){
        System.out.println("speak english...");
    }
    
}
public class iPearV2 extends iPearV1 {
    /*
        2. 定义新手机类 iPearV2
                    call(String name) : 打电话方法
                    smallBlack() : 语音助手 (speak english...  说中文)

       方法重写的应用场景:
            当子类需要父类的功能,而功能主体子类有自己特有内容
            可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容
     */

    public void smallBlack(){
        super.smallBlack();
        System.out.println("说中文");
    }
    
}

2.4.5 方法重写的注意事项

注意事项:

  1. 子类重写父类方法时,方法的访问权限不能比父类更低(一般情况下,子类在重写父类方法的时候,都是让子类的方法访问权限和父类的方法访问权限一致)
  2. 父类静态方法,子类也必须通过静态方法进行重写,父类非静态方法,子类不能通过静态方法进行重写
  3. 父类中私有的方法不能被重写

访问权限修饰符:

修饰符同一个类中同一个包中的子类与无关类不同包中的子类不同包中的无关类
private
默认
protected
public

注:√表示可以访问,没有写表示不能访问

2.4.6 构造方法

方法特点:子类中所有的构造方法默认都会访问父类中无参数的构造方法

为什么构造方法的访问具有这样的特点呢?

因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。其实每一个构造方法的第一条语句默认都是:super()

针对Person类我们没有显示的指定父类,其实默认会继承Jdk中给我们提供的一个类Obejct(Object类是整个继承体系中的顶层父类,它往上就没有父类了)。

思考问题:如果父类中不存在无参数的构造方法,那么子类应该如何进行初始化呢?

1、在子类的构造方法中通过super显示的调用父类有参的构造方法

class Zi extends Fu {
	
    public Zi(int age){
        super(age);
    }
    
}

2、在子类的构造方法中通过this关键字调用本类其他的构造方法,而其他的构造方法中通过super在显示的调用父类有参的构造方法

class Zi extends Fu {

    public Zi(){
        this(10); // super();		// 调用本类其他的构造方法
    }

    public Zi(int age){				
        super(age);					// 调用父类有参的构造方法
    }
    
}

注意事项:this(…)必须是构造方法的第一条语句,并且不能和super(…)共存

对原有的继承代码进行优化:

由于构造方法不能被继承,因此在子类中需要去指定自己特有的构造方法。在进行属性初始化的时候,需要通过super关键字显示的调用父类的构造方法进行初始化,而自己特有的属性,

直接通过this关键字进行赋值即可。

public class Student extends Person {

    // 子类自己特有的属性.
    private int score;

    public Student(){									// 无参构造方法			
        super();										// 调用了父类无参构造方法
    }

    public Student(String name, int age, int score){	// Student的有参构造方法
        super(name,age);								// 通过super关键字显示的调用了父类有参的构造方法,完成name和age的初始化
        this.score = score;								// 把score参数赋值给Student的成员变量score
    }
    
}

继承体系的内存图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zk96H7Dp-1618742814900)(images/image-20210418145621354.png)]

创建了一个子类的对象,是否同时创建了父类对象呢?没有创建父类对象

2.5 信息管理系统进行优化

分为两方面:

1、对Student和Teacher进行优化,将共性的内容抽取到Person类中,让Student和Teacher继承Person

2、对数据的封装才有有参构造方法进行完成

怎么实现?

思路:对StudentController中的inputStudentInfo进行修改,但是这种方式不符合我们开发的一个原则(开闭原则)。开闭原则:对修改进行关闭对扩展进行开放,最好是通过添加代码的

方式对系统进行扩展。那么实现的方式:在创建一个新的StudentController(OtherStudentController),然后在inputStudentInfo方法中进行数据的封装。

经过上述代码的处理以后,系统中目前就存在了两个和Student相关的Controller。

1、StudentController

2、OtherStudentController

而这两个Controller的大部分内容都是相同的,看到相同的内容继续进行优化,使用继承。因此需要编写BaseStudentController,让StudentController和OtherStudentController继承该

类。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YgUZ6ffi-1618742814901)(images/image-20210418153426870.png)]

3 抽象类

3.1 概述

抽象方法:当我们不确定某一个方法的方法体内容的时候,此时就可以不用定义方法体**{}** ,那么这样的方法其实就是抽象方法,并且这个方法需要使用abstract关键字进行修饰。

抽象类:当一个类中出现了抽象方法,那么这个类就必须定义为抽象类。要把一个类定义成抽象类,就需要通过abstract关键字修饰这个类。

抽象方法的定义格式:

public abstract 返回值类型 方法名(参数列表);

抽象类的定义格式:

public abstract class 类名{}

3.2 注意事项

注意事项:

1、抽象类不能被实例化

2、抽象类可以存在构造方法

3、抽象类的子类

  • 可以是抽象类
  • 也可以是具体的类

4、抽象类中可以没有抽象方法,但是如果有抽象方法,那么这个类必须是一个抽象类

3.3 应用场景

什么是设计模式?设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。

简单理解:设计模式就是一套书写代码的风格,设计模式就是一套书写代码套路,自古套路得人心。Java语言中是存在23种设计模式。

使用设计模式的好处:

1、提高代码的复用性

2、提高代码的维护性

3、提高代码的扩展性

模板设计模式到底是什么?

思想:把抽象类整体就可以看做成一个模板,模板中不能决定的东西定义成抽象方法,让使用模板的类(继承抽象类的类)去重写抽象方法实现需求。

模板:是将一个事物的结构规律予以固定化、标准化的成果,它体现的是结构形式的标准化。

CompositionTemplate类

// 作文的模板类
public abstract class CompositionTemplate {

    // 模板方法:定义了代码结构的方法,我们可以将其称之为模板方法
    public void write() {

        // 标题
        System.out.println("<<我的爸爸>>");

        // 作文的正文
        body();

        // 结束语
        System.out.println("啊, 这就是我的爸爸....");

    }

    // 作文的正文的抽象方法
    public abstract void body();

}

TomCompositionTemplate类

// Tom的作文类
public class TomCompositionTemplate extends CompositionTemplate  {

    // 重写父类方法
    @Override
    public void body() {
        System.out.println("我的爸爸是李刚,相当的刚.....");
    }

}

测试类:

TomCompositionTemplate tom = new TomCompositionTemplate() ;
tom.write();

3.4 final关键字

final表示最终的意思,可以修饰的内容如下:

1、方法

  • 特点:不能被子类重写

2、类

  • 特点:不能被子类继承

3、变量

  • 基本数据类型:变量的值不能被改变,只能被赋值一次,这样的变量就是常量(自定义常量),命名规范:字母都是大写,多个单词之间使用"_"进行隔开
  • 引用数据类型:地址值不能被改变

final修饰的成员变量的初始化时机:

1、在定义的时候直接对其进行初始化

public class Student {
    final int a = 23 ;
}

2、在构造方法执行完毕之前进行初始化

public class Student {
    final int a ;
    public Student() {
        a = 23 ;
    }
}

4 总结

1、继承

2、抽象类

3、模板设计模式

4、final关键字



这篇关于JAVA 基础 继承与抽象类的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程