JAVA基础再回首(七)——final关键字、抽象类abstract、接口interface、权限修饰符、导包

JAVA基础再回首(七)——final关键字、抽象类abstract、接口interface、权限修饰符、导包

没有到不了的明天。
嬉皮笑脸面对人生的难。
相信自己,不然你什么都做不了。

final关键字


  • final关键字是最终的意思,可以修饰类,成员变量,成员方法。
    • 修饰类,类不能被继承
    • 修饰变量,变量就变成了常量,只能被赋值一次
    • 修饰方法,方法不能被重写

我们可以写一个Demo来验证一下final关键字
class Fu {
    public int num = 10;
    public final int num2 = 20;

    /*
    public final void show() {
    }
    */
}
class Zi extends Fu {
    // Zi中的show()无法覆盖Fu中的show()
    public void show() {
        num = 100;
        System.out.println(num);
        //无法为最终变量num2分配值
        //num2 = 200; //打开注释会报错
        System.out.println(num2);
    }
}
public class FinalDemo{
    public static void main(String[] args) {
        Zi z = new Zi();
        z.show();
    }
}

输出结果:
100
20

那么final在继承中如何体现呢?

由于继承中方法有一个现象:方法重写。所以,父类的功能就会被子类覆盖掉。有时候为了不让子类去覆盖掉父类的功能,只能让他用,所以,针对这种情况,java就提供了一个关键字:final。

class Fu {
    public final void show() {
        System.out.println("这里是绝密资源,任何人都不能修改");
    }
}
class Zi extends Fu {
    // Zi中的show()无法覆盖Fu中的show()
//  public void show() {
//      System.out.println("这是一堆垃圾");
//  }
}
public class FinalDemo{
    public static void main(String[] args) {

        Zi z = new Zi();
        z.show();
    }
}

输出结果:
肯定是父类中的输出结果了。

抽象类(abstract)

概述:
动物不应该定义为具体的东西,而且动物中的吃,睡等也不应该是具体的。
我们把一个不是具体的功能称为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类。

  • 抽象类特点
    • 抽象类和抽象方法必须用abstract关键字修饰
      • 格式
      • abstract class 类名 {}
      • public abstract void eat();
    • 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
    • 抽象类不能实例化
      • 因为它不是具体的。
      • 那么,抽象类如何实例化呢?
      • 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
    • 抽象类的子类
      • 如果不想重写抽象方法,该子类是一个抽象类。
      • 重写所有的抽象方法,这个时候子类是一个具体的类。
abstract class Animal {
    //抽象方法
    //public abstract void eat(){} //空方法体,这个会报错。抽象方法不能有主体
    public abstract void eat();

    public Animal(){}
}

//子类是抽象类
abstract class Dog extends Animal {}

//子类是具体类,重写抽象方法
class Cat extends Animal {
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

输出结果:猫吃鱼

  • 抽象类的成员特点:
    • 成员变量:既可以是变量,也可以是常量。
    • 构造方法:构造方法不能被实例化。所以构造方法的特点是:用于子类访问父类数据的初始化。
  • 抽象类的成员方法特性:
    • 可以有抽象方法,强制要求子类做的事情。
    • 也可以有非抽象方法,子类继承的事情,提高代码复用性。
abstract class Animal {
    public int num = 10;
    public final int num2 = 20;

    public Animal() {}

    public Animal(String name,int age){}

    public abstract void show();

    public void method() {
        System.out.println("method");
    }
}


class Dog extends Animal {
    public void show() {
        System.out.println("show Dog");
    }
}
public class AbstractDemo {

    public static void main(String[] args) {
                //创建对象
                Animal a = new Dog();
                a.num = 100;
                System.out.println(a.num);
                //a.num2 = 200;
                System.out.println(a.num2);
                System.out.println("--------------");
                a.show();
                a.method();
    }
}

输出结果:
这里写图片描述

我们学习了抽象方法,但是让我有两个疑惑的问题,不知道你们是不是也同样疑惑,我给大家解答一下。

  1. 一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?

    答案肯定是可以的,意义就是为了不让创建对象。

  2. abstract不能和哪些关键字共存?

    private冲突、final冲突、static无意义
    下面我们实例一个Demo

public class AbstractDemo {

    public static void main(String[] args) {
        Father.methods();
    }
}
abstract class Father{
    //public abstract void show();
    //非法的修饰符组合: abstract和private
    //private abstract void show();

    //非法的修饰符组合  abstract和final
    //final abstract void show();   

    //非法的修饰符组合abstract和static 
    //static abstract void show();

    public static void methods() {
        System.out.println("method");
    }
}

class Son extends Father {
    public void show() {}
}

接口(interface)

  • 接口用关键字interface表示
    • 格式:interface 接口名 {}
  • 类实现接口用implements表示
    • 格式:class 类名 implements 接口名 {}
  • 接口不能实例化
    • 那么,接口如何实例化呢?
    • 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态(下一节讲)。
  • 接口的子类
    • 可以是抽象类。但是意义不大。
    • 可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
//定义动物培训接口
interface AnimalTrain {
    public abstract void jump();
}
//抽象类实现接口
abstract class Dog implements AnimalTrain {
}
//具体类实现接口
class Cat implements AnimalTrain {
    public void jump() {
        System.out.println("猫可以跳高了");
    }
}
public class InterfaceDemo {

    public static void main(String[] args) {
                //AnimalTrain是抽象的; 无法实例化
                //AnimalTrain at = new AnimalTrain();
                //at.jump();

                AnimalTrain at = new Cat();
                at.jump();
    }
}

输出结果:猫可以跳高了

  • 接口成员特点
    • 成员变量;只能是常量,并且是静态的。
    • 默认修饰符:public static final
    • 建议:自己手动给出。
  • 构造方法:接口没有构造方法。因为接口主要是扩展功能的,而没有具体存在
  • 成员方法:只能是抽象方法。
    • 默认修饰符:public abstract
    • 建议:自己手动给出。
interface Inter {
    public int num = 10;
    public final int num2 = 20;
    public static final int num3 = 30;

    //错误: 需要<标识符>,接口没有构造方法
    //public Inter() {}

    //接口方法不能带有主体
    //public void show() {}

    //abstract void show(); //默认public
    public void show(); //默认abstract
}

class InterImpl extends Object implements Inter {
    public InterImpl() {
        super();
    }

    @Override
    public void show() {

    }
}
public class InterfaceDemo {

    public static void main(String[] args) {
                //创建对象
                Inter i = new InterImpl();
                System.out.println(i.num);
                System.out.println(i.num2);
                //i.num = 100;
                //i.num2 = 200;
                //System.out.println(i.num); //无法为最终变量num分配值
                //System.out.println(i.num2);//无法为最终变量num2分配值
                System.out.println(Inter.num);
                System.out.println(Inter.num2);

    }
}

输出结果:
10
20
10
20

类与类,类与接口以及接口与接口的关系

觉得他们的关系好复杂,快看晕了,没关系,我们逐个学习

  • 类与类:
    • 继承关系,只能单继承,可以多层继承。
  • 类与接口:
    • 实现关系,可以单实现,也可以多实现。
    • 并且还可以在继承一个类的同时实现多个接口。
  • 接口与接口:
    • 继承关系,可以单继承,也可以多继承
interface Father{
    public abstract void show();
}

interface Mother {
    public abstract void show2();
}

interface Sister extends Father,Mother {

}
class Son extends Object implements Father,Mother {
    public void show() {
        System.out.println("show son");
    }

    public void show2() {
        System.out.println("show2 son");
    }
}
public class InterfaceDemo {

    public static void main(String[] args) {
                //创建对象
                Father f = new Son();
                f.show();
                //f.show2(); //报错

                Mother m = new Son();
                //m.show(); //报错
                m.show2();

    }
}

输出结果:
show2 son
show son

上面我们学习了抽象类,又学习了接口。那么他们之间有什么区别呢?我们继续开车…

抽象类和接口的区别

  • 成员区别

    • 抽象类:
      • 成员变量:可以变量,也可以常量
      • 构造方法:有
      • 成员方法:可以抽象,也可以非抽象
    • 接口:
      • 成员变量:只可以常量
      • 成员方法:只可以抽象
  • 关系区别

    • 类与类
      • 继承,单继承
    • 类与接口
      • 实现,单实现,多实现
    • 接口与接口
      • 继承,单继承,多继承
  • 设计理念区别
    • 抽象类
      • 被继承体现的是:”is a”的关系。
      • 抽象类中定义的是该继承体系的共性功能。
    • 接口
      • 被实现体现的是:”like a”的关系。
      • 接口中定义的是该继承体系的扩展功能。

权限修饰符

  • 修饰符:
    • 权限修饰符:private,默认的,protected,public
    • 状态修饰符:static,final
    • 抽象修饰符:abstract
  • 类:
    • 权限修饰符:默认修饰符,public
    • 状态修饰符:final
    • 抽象修饰符:abstract
      • 用的最多的就是:public
  • 成员变量:
    • 权限修饰符:private,默认的,protected,public
    • 状态修饰符:static,final
      • 用的最多的就是:private
  • 构造方法:
    • 权限修饰符:private,默认的,protected,public
      • 用的最多的就是:public
  • 成员方法:
    • 权限修饰符:private,默认的,protected,public
    • 状态修饰符:static,final
    • 抽象修饰符:abstract
      • 用的最多的就是:public
  • 除此以外的组合规则:
    • 成员变量:
      • public static final
    • 成员方法:
      • public static
      • public abstract
      • public final

最后我们在学一个小知识点——>导包

导包

  • 导包概述
    • 不同包下的类之间的访问,我们发现,每次使用不同包下的类的时候,都需要加包的全路径。比较麻烦。这个时候,java就提供了导包的功能。
  • 导包格式
    • import 包名;
  • 注意:
    • 我们用那个报就导那个包。

那么,package,import,class有没有顺序关系?

答案是肯定有关系。
package > import > class
Package:只能有一个
import:可以有多个
class:可以有多个,以后建议是一个


今天我们就学到这里,明天我们来学习多态。

最后呢,欢迎有兴趣的同学加我朋友的QQ群:555974449
群主呢,也就是我在第一篇博客我毕业了中给大家提到的刘某人程序员
我们在群里等你!

发布了39 篇原创文章 · 获赞 84 · 访问量 12万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章