抽象类、接口、内部类和枚举

本文详细解析了Java中抽象类、接口、内部类和枚举的概念与用法,包括抽象方法、多继承、成员变量、构造方法等关键特性,以及自定义枚举和枚举实现接口的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章内容输出来源:拉勾教育大数据开发高薪训练营

一、抽象类

    1. 抽象方法:

不能具体实现的方法并且使用abstract关键字修饰,没有方法体。

    2. 语法:访问权限 abstract 返回值类型 方法名(形参列表);

    3. 抽象类:

        不能具体实例化的类并且使用abstract关键字修饰,也就是不能创建对象;

    4. 抽象类与抽象方法:

a. 抽象类中可以有成员变量、构造方法、成员方法

b. 抽象类中可以没有抽象方法,也可以有抽象方法;

c. 拥有抽象方法的类必须是抽象类,因此真正意义上的抽象类应该是具有抽象方法并且使用abstract关键字修饰的类。

    注: 当子类继承抽象类,必须重写抽象类中的抽象方法,否则,子类必须声明为抽象类;

public abstract class AbstractTest {
    private int cnt;

    public AbstractTest() {
    }

    public AbstractTest(int cnt) {
        setCnt(cnt);
    }

    public int getCnt() {
        return cnt;
    }

    public void setCnt(int cnt) {
        this.cnt = cnt;
    }

    // 自定义抽象方法
    public abstract void show();

}

 


二、接口

    1. 概念:

        所有方法都是抽象方法,关键字interface;类与接口间可以支持多实现,接口与接口间可以支持多继承;

    2. 抽象类与接口的区别(注重理解记忆):

• 定义抽象类的关键字是abstract class,而定义接口的关键字是interface。

• 继承抽象类的关键字是extends,而实现接口的关键字是implements。

• 继承抽象类支持单继承,而实现接口支持多实现

• 抽象类中可以有构造方法,而接口中不可以有构造方法

• 抽象类中可以有成员变量,而接口中只可以有常量

• 抽象类中可以有成员方法,而接口中只可以有抽象方法

• 抽象类中增加方法时子类可以不用重写,而接口中增加方法时实现类需要重写(Java8以前的版本)。

• 从Java8开始增加新特性,接口中允许出现非抽象方法和静态方法,但非抽象方法需要使用default关键字修饰

• 从Java9开始增加新特性,接口中允许出现私有方法。

public interface InterfaceTest {
    
    // 接口中只能有常量,因此public static final可省略
    
    public static final int CNT = 1;     // 里面只能有常量
    //private void show(){}              // 从Java9开始允许接口中出现私有方法
    public abstract void show();         // 里面只能有抽象方法(新特性除外)
}

 


三、内部类

  1. 内部类:出现在另一个类的类体中的类;

  2. 一个类的类体中可以出现:成员变量、成员方法、构造方法、静态成员、构造块和静态代码块、以及内部类;

  3. 四种内部类


四、枚举类

     1.枚举的基本概念:

        在日常生活中一些些事物的取值只有明确的几个固定值,比如一年四季:春夏秋冬;性别:男女;键盘上的方向键:上下左右;此时描述这些事物的所有值都可以一一列举出来,而这个列举出来的类型就叫做枚举类型。

     2.自定义实现枚举:

  定义一个方向类:

/**
 * 编程实现所有方向的枚举,所有的方向:向上、向下、向左、向右
 */
public class Direction {
    private final String desc; // 用于描述方向字符串的成员变量

    // 2.声明本类类型的引用指向本类类型的对象
    public static final Direction UP = new Direction("向上");
    public static final Direction DOWN = new Direction("向下");
    public static final Direction LEFT = new Direction("向左");
    public static final Direction RIGHT = new Direction("向右");

    // 通过构造方法实现成员变量的初始化,更加灵活
    // 1.私有化构造方法,此时该构造方法只能在本类的内部使用
    private Direction(String desc) {
        this.desc = desc;
    }

    // 通过公有的get方法可以在本类的外部访问该类成员变量的数值
    public String getDesc() {
        return desc;
    }
}

测试:

public class DirectionTest {

    public static void main(String[] args) {

        /*
        // 1.声明Direction类型的引用指向该类型的对象并打印特征
        Direction d1 = new Direction("向上");
        System.out.println("获取到的字符串是:" + d1.getDesc()); // 向上

        Direction d2 = new Direction("向下");
        System.out.println("获取到的字符串是:" + d2.getDesc()); // 向下

        Direction d3 = new Direction("向左");
        System.out.println("获取到的字符串是:" + d3.getDesc()); // 向左

        Direction d4 = new Direction("向右");
        System.out.println("获取到的字符串是:" + d4.getDesc()); // 向右


        System.out.println("-------------------------------------");
        Direction d5 = new Direction("向前");
        // 向前   与需求不符合 原因是能new出来的对象太多
        System.out.println("获取到的字符串是:" + d5.getDesc()); */
            
        // 此时的解决方式是私有化构造方法,但是构造方法私有化后,以上程序报错,并且私有化构造方法
        // 后new出来的对象太少,因此将Direction类改造如上2.

        /* 错误使用 */
        //Direction.UP = 2; Error:类型不匹配
        //Direction d2 = null;
        //Direction.UP = d2; Error: final关键字修饰

        Direction d1 = Direction.UP;
        System.out.println("获取到的方向是:" + d1.getDesc()); // 向上
}

 

     3.Java5新增的引用数据类型:enum(枚举) 

使用enum实现枚举:

/**
 * 枚举类型要求所有枚举值必须放在枚举类型的最前面
 */
public enum DirectionEnum {
    // 2.声明本类类型的引用指向本类类型的对象
    
    UP("向上"), DOWN("向下"), LEFT("向左"), RIGHT("向右");

    private final String desc; // 用于描述方向字符串的成员变量

    // 通过构造方法实现成员变量的初始化,更加灵活
    // 1.私有化构造方法,此时该构造方法只能在本类的内部使用
    private DirectionEnum(String desc) { this.desc = desc; }

    // 通过公有的get方法可以在本类的外部访问该类成员变量的数值
    public String getDesc() {
        return desc;
    }
}

测试:

public class DirectionTest {

    public static void main(String[] args) {

        // 使用一下Java5开始的枚举类型
        DirectionEnum de = DirectionEnum.DOWN;
        System.out.println("获取到的方向是:" + de.getDesc()); // 向下
    }
}

 

     4.总结:枚举的定义:

  • Java5新增的引用数据类型:enum(枚举) ,使用时要求所有枚举值必须放在枚举类型的最前面;
  • 枚举值就是当前类的类型,也就是指向本类的对象,默认使用public static final关键字共同修饰,因此采用枚举类型.的方式调用。
  • 枚举类可以自定义构造方法,但是构造方法的修饰符必须是private,默认也是私有的;

     5.自定义枚举与enum在switch中的使用:

public class DirectionUseTest {

    // 自定义枚举实现
    public static void test1(String str) {
        switch (str) {
            case "向上":
                System.out.println("抬头望明月!"); break;
            case "向下":
                System.out.println("低头思故乡!"); break;
            case "向左":
                System.out.println("左牵黄"); break;
            case "向右":
                System.out.println("右擎苍"); break;
            default:
                System.out.println("没有这样的方向哦!");
        }
    }

    // enum实现
    public static void test2(DirectionEnum de) {
        switch (de) {
            case UP:
                System.out.println("抬头望明月!"); break;
            case DOWN:
                System.out.println("低头思故乡!"); break;
            case LEFT:
                System.out.println("左牵黄"); break;
            case RIGHT:
                System.out.println("右擎苍"); break;
            default:
                System.out.println("没有这样的方法哦!");
        }
    }

    public static void main(String[] args) {

        DirectionUseTest.test1(Direction.UP.getDesc());
        DirectionUseTest.test1("今天是个好日子!");   // 打印没有这样的方向哦!

        System.out.println("--------------------------------------------");

        DirectionUseTest.test2(DirectionEnum.DOWN);
        //DirectionUseTest.test2("今天是个好日子!"); Error:类型不匹配,减少了出错的可能性
    }
}

 

     6.Enum类:

     7.枚举类实现接口的方式:

定义接口: 

public interface DirectionInterface {
    // 自定义抽象方法
    public abstract void show();
}

实现接口:

public enum DirectionEnum implements DirectionInterface {
    // 2.声明本类类型的引用指向本类类型的对象
    // 匿名内部类的语法格式:接口/父类类型 引用变量名 = new 接口/父类类型() { 方法的重写 };
    // public static final Direction UP = new Direction("向上") { 方法的重写 };
    UP("向上") {
        @Override
        public void show() {
            System.out.println("贪吃蛇向上移动了一下!");
        }
    }, DOWN("向下") {
        @Override
        public void show() {
            System.out.println("贪吃蛇向下移动了一下!");
        }
    }, LEFT("向左") {
        @Override
        public void show() {
            System.out.println("左移了一下!");
        }
    }, RIGHT("向右") {
        @Override
        public void show() {
            System.out.println("右移了一下!");
        }
    };

    private final String desc; // 用于描述方向字符串的成员变量

    // 通过构造方法实现成员变量的初始化,更加灵活
    // 1.私有化构造方法,此时该构造方法只能在本类的内部使用
    private DirectionEnum(String desc) { this.desc = desc; }

    // 通过公有的get方法可以在本类的外部访问该类成员变量的数值
    public String getDesc() {
        return desc;
    }

    // 整个枚举类型只重写一次,所有对象调用同一个
    /*@Override
    public void show() {
        System.out.println("现在可以实现接口中抽象方法的重写了!");
    }*/
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值