JAVA 知识 回顾 2

2020-10-10  本文已影响0人  WhiteStruggle

面向对象

继承

关键字: extends

特点:

  1. 提高代码的复用性
  2. 让类与类之间产生关系,才有了多态的特性

注意:

  1. 不能为了获取其他类的功能,简化代码而继承
  2. 必须类与类有所属关系才可以继承。所属关系

Java语言中只支持单继承,不支持多继承

多继承存在安全隐患,当多个父类中定义了相同的功能,但功能内容不同是,子类对象不确定运行哪一个

Java保留了多继承机制,并用另一种形式体现,接口(多实现,implements)

public class Main {
    public static void main(String[] args)
    {
        Student s1 = new Student();
        s1.setName("Yz");
        s1.setAge(25);
        s1.study();
    }
}
/**
    设置父类,保存通用的一些属性,
    不要设置私有,否则继承无法获取
*/
class People{
    protected String name;
    protected int age;
}
/**
    子类继承People父类
*/
class Student extends People
{
    public void setName(String name){
        this.name = name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public void study()
    {
        System.out.println("My name is"+this.name);
        System.out.println(this.age+" years old");
    }
}

多层继承

Java支持多层继承,也就是有一个继承体系

想要使用体系,先要查阅父类的藐视,因为弗雷中定义的是该类中共性功能

通过了解共性功能,就可以知道该体系的基本功能

查阅父类功能,创建子类对象使用功能

class People
{
    ·····
}
class Student extends People
{
    ·····
}
class Children extends Student 
{
    ·····
}

聚集关系

按照事物联系的紧密程度划分为

聚合:例如球队与球员关系,缺少队员是可行的

组合:例如人与人体器官的关系,缺少器官是万万不行的

子父类关系

类中成员:

  1. 变量
  2. 函数
  3. 构造函数

super —— 父类对象引用

子类要访问本类变量用 this

子类访问父类中的同名变量用 super

public class Main {
    public static void main(String[] args)
    {
        Student s = new Student();
        s.showAge();
    }
}
class People{
    protected int age = 25;
}
/**
    类中的变量,引用默认为this
*/
class Student extends People
{
    int age = 2;
    public void showAge(){
        System.out.println(age);//2
        System.out.println(this.age);//2
        System.out.println(super.age);//25
    }
}

重写(覆盖)

子父类的方法名相同

当子类继承父类,会沿袭父类的功能,到子类中,但子类中虽具备该功能,但功能内容不一样

这时,没必要定义新功能,而是使用覆盖,保留父类的功能定义,并重写内容功能

注意:

  1. 子类覆盖父类,必须保证子类权限大于父类权限,才可以覆盖,否则编译失败
  2. 静态只能覆盖静态

权限问题:
public > 没有修饰 > private

/**
    子类speak() 会覆盖 父类 的 speak()
*/
public class Main {
    public static void main(String[] args)
    {
        Student s = new Student();
        s.speak();//你好 , 世界!!
    }
}
//父类
class People{
    public void speak(){
        System.out.println("Hello WOrld!!!");
    }
}
//子类
class Student extends People
{
    public void speak(){
        System.out.println("你好 , 世界!!");
    }
}

当子类继承父类的功能,并添加一些新的内容

/**
    通过super在子类功能
*/

//子类
class Student extends People
{
    public void speak(){
        super.speak();
        System.out.println("你好 , 世界!!");
    }
}

重载:值看同名函数的参数列表

重写(覆盖):字符类方法要一模一样

子父类构造函数

super(); —— 引用父类空参数的构造函数

this(); —— 引用本类的构造函数

在子类对象进行初始化时,父类构造函数也会运行,因为子类构造函数默认第一行有一条隐式的 super();

super();语句必须放在第一行

子类中 所有的构造函数第一行默认都 是 super();

public class Main {
    public static void main(String[] args)
    {
        Student s = new Student();
        Student s1 = new Student(25);
//        This is People
//        This is Student
//        This is People
//        age:25
    }
}
class People{
    People(){
        System.out.println("This is People");
    }
}
class Student extends People
{
    Student(){
        System.out.println("This is Student");
    }
    Student(int age){
        System.out.println("age:"+age);
    }
}

子类一定要访问父类中的构造函数

因为子类对象在建立时,需要先查看父类是如何对这些数据进行初始化,所以子类在对象初始化时,要先访问一下父类中的构造函数

要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定

public class Main {
    public static void main(String[] args)
    {
        Student s = new Student();
//        num:58
//        This is Student
    }
}
class People{
    People(){
        System.out.println("This is People");
    }
    People(int num){
        System.out.println("num:"+num);
    }
}
class Student extends People
{
    Student(){
        super(58);
        System.out.println("This is Student");
    }
}

子类的所有构造函数,默认都会访问父类中的空参数构造函数

当父类中没有空参数构造函数时,子类必须手动通过super或者this语句形式来指定要访问的构造函数

子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数

子类中至少会有一个构造函数会访问父类的构造函数

所有类继承自 object类

final关键字

final:最终

修饰符:

  1. 可以修饰类,函数,变量
  2. 被final修饰的 类不可以被继承
  3. 被final修饰的 方法不能被复写
  4. 被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,也可以修饰局部变量
  5. 内部类定义在类中的局部位置上,只能访问该局部被final修饰的局部变量

final修饰的变量,称为常量,所有的的字母都是大写,若由多个单词组成,使用连接符( _ )连接

抽象类()

当多个类中出现相同功能,但功能主体不同,这时可以进行抽取,抽取功能定义,而不抽取功能主体

class All{
    void show(){};
}
class A extends All{
    void show(){
        System.out.println("A");
    }
}
class B extends All{
    void show(){
        System.out.println("B");
    }
}

抽象类:abstract,不必在意内容

特点:

  1. 抽象方法一定在抽象类中
  2. 抽象方法和抽象类必须被abstract关键字修饰
  3. 抽象类不可以用 new 创建对象,因为调用抽象方法没意义
  4. 抽象类中的抽象方法要被使用,必须有子列复写所有的抽象方法后,建立子类对象调用

若子类支付该部分抽象方法,则该子类还是一个抽象类

abstract class All{
    abstract void show();
    abstract void set();
}
class A extends All{
    void show(){
        System.out.println("A");
    };
    void set(){};
}
class B extends All{
    void show(){
        System.out.println("B");
    }
    void set(){};
}

继承抽象类,会强制子类进行一些方法

抽象类和一般类没有太大的不同

抽象类不可以实例化

抽象类比一般类多了个抽象函数,就是在类中可以定义抽象方法

抽象类中可以不定义抽象方法,目的 : 不让该类建立对象

模板方法模式

在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部,
那么就将不确定的部分暴露,公外部程序继承使用

获取当前的时间戳

System.currentTimeMillis()

public class Main {
    public static void main(String[] args)
    {
        SetTime s1 = new SetTime();
        System.out.println(s1.getTime());
    }
}
abstract class GetTime
{
    /*
     * System.currentTimeMillis(); 获取当前时间的时间戳
     * runRode(); 一个接口,从而运行外部程序
     */
    public final long getTime(){
        Long start = System.currentTimeMillis();
        runRode();
        Long end = System.currentTimeMillis();
        return end-start;
    }
    /*
     *  一个接口,可以被继承,然后重载,通过抽象
     */
    public abstract void runRode();
}
/*
 * 自类继承父类的内容,同时通过重载runRode,来获取runRode中程序的执行时间
 */
class SetTime extends GetTime{
    public void runRode(){
        for (int i = 0; i < 2000; i++) {
            System.out.print(2);
        }
        System.out.println();
    }
}

接口

初期理解:特殊的抽象类(抽象类中的全部方法都是抽象的)

interface —— 用于定义接口

class —— 用于定义类

格式特点:

  1. 接口中常见的定义:常量,抽象方法
  2. 接口中的成员都有固定修饰符
    • 常量 —— public static final
    • 方法 —— public abstract

接口中的成员都是public

默认情况下,只要定义 interface ,接口成员的修饰符会默认,可以不写或者少写

通常情况下,要写全,方便阅读

interface Circle{
    public static final double PI = 3.14;
    public abstract double show();
}

接口是不可以创建方法的,因为有抽象方法,需要被子类实现,子类对接口中的抽象方法全部覆盖后,子类才可以实现实例化,否则子类是一个抽象类

s使用子类引用接口时,不能使用继承 extends ,而应该用 实现 implements

public class Main {
    public static void main(String[] args)
    {
        Area s = new Area(8);
        System.out.println(s.show());
    }
}

//定义一个接口 
interface Circle{
    public static final double PI = 3.14;
    public abstract double show(int r);
}
//计算圆的面积,接口定义的内容,不能使用继承 extends,应该使用实现 implements
class Area implements Circle,Rect{
    private double r;
    Area(double r)
    {
        this.r = r;
    }
    public double show(){
        double R = this.r;
        return PI*R*R;
    }
}

类与类之间是继承 extends

类与接口之间 是 实现 Implements

接口可以被类多实现(implements),Java支持多实现(implements)

interface Circle{
    public static final double PI = 3.14;
    public abstract double show();
}
interface Rect{
    public abstract double show();
}
class Area implements Circle,Rect{
    public double show(){
        return PI;
    };
}

接口与接口之间,是继承 , 允许存在多继承

interface Circle{
    public abstract void circle();
}
interface Rect{
    public abstract void rect();
}
interface All extends Circle,Rect{
    public  abstract void all();
}
class Show implements All{
    public void circle(){};
    public void rect(){};
    public void all(){};
}

接口特点

  1. 接口对外暴露规则
  2. 接口时程序的功能扩展,降低耦合性
  3. 接口可以用来多实现
  4. 类域接口之间是实现关系,类可以继承一个类的同事实现多个接口
  5. 接口与接口之间可以有继承关系

接口实例

基本内容定义在类中

扩展功能定义在接口中

public class Main {
    public static void main(String[] args)
    {
        Worker w = new Worker();
        w.sleep();//睡觉了!
        w.speak();//我是工人,我需要工作!
        w.work();//搬砖
        Student s = new Student();
        s.sleep();//睡觉了!
        s.speak();//我是学生,不需要工作!
    }
}

//抽象类,抽象方法speak , 一般方法 sleep
abstract class People{
    abstract void speak();
    void sleep(){
        System.out.println("睡觉了!");
    }
}
//接口,扩展一个工作
interface Working{
    public abstract void work();
}
/*
 *  这是一个工人类
 *      继承 sleep
 *      抽象 speak
 *      实现 work
 */
class Worker extends People implements Working{
    void speak() {
        System.out.println("我是工人,我需要工作!");
    }
    void sleep() {
        super.sleep();
    }
    public void work() {
        System.out.println("搬砖");
    }
}

/*
 *  这是一个学生类
 *      继承sleep
 *      抽象speak
 */
class Student extends People{
    void speak() {
        System.out.println("我是学生,不需要工作!");
    }
    void sleep() {
        super.sleep();
    }
}

多态

可以理解为 事物存在的多种体现形态

多态的体现:

父类的引用指向了自己的子类对象

父类的引用可以接受自己的子类对象

但是产生的对象不能调用子类的方法

多态的前提

必须是类与类之间的关系,继承或实现

通常子类覆盖父类

多态的前提

提高了扩展性,但是只能使用父类的引用访问父类的成员

多态的好处

多态的出现大大提高了程序的扩展性
public class Main {
    public static void main(String[] args)
    {
        // 原本的方式
        People s = new Student();
        s.speak();

        // 封装的方法
        function(new Worker());
    }
    public static void function(People p)
    {
        p.speak();
    }
}

abstract class People{
    abstract void speak();
    // 可以每添加一个子类,就可以添加一些子类的方法,用于被覆盖
}
class Worker extends People  {
    void speak() {
        System.out.println("我是工人,我需要工作!");
    }
}
class Student extends People  {
    void speak() {
        System.out.println("我是学生,我需要学习!");
    }
    public void work() {
        System.out.println("学习");
    }
}

转型

类型提升,向上转型

People s = new Student();  

若要调用子类的特有的方法时,强制将父类引用转成子类类型,向下转型

Student c = (Student)s;

不能将父类对象转化成子类类型

应用

子类覆盖父类的方法

当通过父类 去引用子类方法,会执行覆盖之后的方法

public class Main {
    public static void main(String[] args) {
        // 封装的方法
        function(new Student());
    }
    public static void function(People p)
    {
        p.speak();
        p.sleep();
    }
}

abstract class People{
    abstract void speak();
    // 可以每添加一个子类,就可以添加一些子类的方法,用于被覆盖
    public void sleep() {
        System.out.println("睡觉");
    }
} class Worker extends People  {
    void speak() {
        System.out.println("我是工人,我需要工作!");
    }
}
 class Student extends People  {
    void speak() {
        System.out.println("我是学生,我需要学习!");
    }
    public void sleep() {
        System.out.println("熬夜啊,不能睡");
    }
}

结果:

我是学生,我需要学习!
熬夜啊,不能睡

多态的特点

编译看左边,运行看右边

People p = new Student();

在多态中,成员变量的特点 :

在多态中,静态成员函数的特点:

public class Main {
    public static void main(String[] args) {
        People p = new Student();
        p.sleep();//睡觉

        Student s = new Student();
        s.sleep();//熬夜啊,不能睡
    }
}

abstract class People{
    public static void sleep() {
        System.out.println("睡觉");
    }
}
 class Student extends People  {
    public static void sleep() {
        System.out.println("熬夜啊,不能睡");
    }
}
上一篇 下一篇

猜你喜欢

热点阅读