Java基础10-面向对象高级:final、单例类、枚举类、抽象类、接口

前言:

这个系列记录了我学习面向语言Java的完整过程,可以当作笔记使用。

每篇文章都包含可运行的代码示例和常见错误分析,尤其适合没有编程经验的读者。学习时建议先准备好安装JDK(Java Development Kit)和IDEA(IntelliJ IDEA集成开发环境),随时尝试修改示例代码。

一,关键字final

1,认识final:

final 关键字是最终的意思,可以修饰:类、方法、变量

  • 修饰类:该类被称为最终类,特点是不能被继承了。
  • 修饰方法:该方法被称为最终方法,特点是不能被重写了。
  • 修饰变量:该变量有且仅能被赋值一次。

注:

1,final修饰基本类型的变量,变量存储的数据不能被改变

2,final修饰引用类型的变量,变量存储的地址不能被改变,但地址所指向对象的内容是可以被改变的。

例如:

final int[] arr = {11, 22, 33, 44};
// arr = new int[]{33, 55, 44}; // 错误:不能修改地址值
arr[2] = 90; // 正确:可以修改数组内容

2,常量:

使用了static final修饰的成员变量就被称为常量

作用:常用于记录系统的配置信息。

例如:

注:

常量的名称,建议全部大写,多个单词用下划线链接

例如:

public static final String SCHOOL_NAME = "玄武";

优势、执行原理:

程序编译后,常量会被“宏替换”:出现常量的地方全部会被替换成其记住的字面量,这样可以保证使用常量和直接用字面量性能是一样的

二,单例类(设计模式)

什么是设计模式:

1,一个问题通常有 n 种解法,其中肯定有一种解法是最优的,这个最优的解法被人总结出来了,称之为设计模式

2,设计模式有20多种,对应20多种软件开发中会遇到的问题。

关于设计模式,主要学什么? 

01 解决什么问题

02 怎么写

注:为了不把A类的唯一对象弄丢(例如:A.a = null),需设计为以上两种示例方式的任意一种来防止对象改变。

应用场景,如:

单例类有很多形式:

饿汉式单例:拿对象时,对象早就创建好了。

懒汉式单例:拿对象时,才开始创建对象。

写法:

  • 把类的构造器私有。
  • 定义一个静态变量用于存储对象。
  • 提供一个静态方法,保证返回的是同一个对象。

三,枚举类

1,认识枚举类:

枚举类是一个特殊类

写法:

新增的几个方法:

继承的父类Enum的3个方法:1,toString()方法(重写后的);2,name()方法;3,ordinal()方法

父类Enum里重写的toString()方法:  

示例:

public static void main(String[] args) {
    A a1 = A.X;
    System.out.println(a1); // 输出X,隐式调用a1.toString()

    A a2 = A.Y;
    System.out.println(a2); // 输出Y

    System.out.println(a1.name()); // 输出X
    System.out.println(a2.name()); // 输出Y
    System.out.println(a1.ordinal()); // 输出索引0
    System.out.println(a2.ordinal()); // 输出索引1
}
 

运行结果:

X
Y
X
Y
0
1
 

总结:
枚举实例 = 单例模式的一种实现方式
枚举类 ≠ 单例类(除非只有一个枚举常量)
枚举类不能被继承(默认final)
抽象类可以被继承(除非用final修饰)

2,枚举的应用场景:

示例:

不用枚举时:

public class Test2 {
    public static void main(String[] args) {
        // 目标:掌握枚举类的应用场景:做信息的分类和标识
        // 需求:模拟上下左右移动图片。
        // 第一种是常量做信息标志和分类。
        move(Constant.UP);
    }

    public static void move(int direction) {
        // 根据这个方向做移动:上下左右。
        switch (direction) {
            case Constant.UP:
                System.out.println("向上移动");
                break;
            case Constant.DOWN:
                System.out.println("向下移动");
                break;
            case Constant.LEFT:
                System.out.println("向左移动");
                break;
            case Constant.RIGHT:
                System.out.println("向右移动");
                break;
            default:
                System.out.println("输入有误");
        }
    }
}

缺点:move方法传入的数值不受约束。

用枚举时:

public class Test2 {
    public static void main(String[] args) {
        // 第二种是枚举做信息标志和分类:参数值受枚举类约束。
        move2(Direction.UP);
    }

    public static void move2(Direction direction) {
        // 根据这个方向做移动:上下左右。
        switch (direction) {
            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("输入有误");
        }
    }
}

优点:数值受限制,而传参时会有提示,如:

注:switch--case里,会自动去找对应的枚举类是谁,类名.XXX类名.可以省略

四,抽象类

1,认识抽象类:

在 Java 中,abstract 是一个关键字,意为 “抽象”,可用于修饰成员方法

  • 用 abstract 修饰类,该类就是抽象类
  • 用 abstract 修饰方法,该方法就是抽象方法

抽象类和抽象方法的语法格式示例:

修饰符 abstract class 类名{
    修饰符 abstract 返回值类型 方法名称(形参列表);
}

// 示例
public abstract class A {
    // 抽象方法:必须用 abstract 修饰,只有方法签名,不能有方法体
    public abstract void test();
}

注:抽象类的使命就是为了给子类继承。

2,好处、应用场景:

好处:

父类知道每个子类都要做某个行为,但每个子类具体做法不同时,父类会将该行为定义为抽象方法,交由子类重写实现。设计这样的抽象类,是为了更好地支持多态

应用:

作为父类的Animal也可以是普通类,但不符合最佳实践

3,模板方法设计模式:

示例:

五,接口

1,接口概述:

示例:

2,接口的好处:

示例:

3,JDK 8新增的三种方法:

好处:更便于项目的扩展和维护

例如:多个实现类实现了接口A后期需要新增一个方法,此时可以新增一个实例方法,不用重写所有的实现类。

4,理解接口的几点注意事项:

1、接口与接口可以多继承:一个接口可以同时继承多个接口[重点]。

类与类: 单继承 一个类只能继承一个直接父类

类与接口: 多实现,一个类可以同时实现多个接口。

接口与接口: 多继承,一个接口可以同时继承多个接口。

 

2、一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承,也不支持多实现

4、一个类继承了父类,又同时实现了接口,如果父类中和接口中有同名的默认方法,实现类会优先用父类的

5、一个类实现了多个接口,如果多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。

5,抽象类和接口的区别:

相同点:

1、多是抽象形式,都可以有抽象方法,都不能创建对象。

2、都是派生子类形式:抽象类是被子类继承使用,接口是被实现类实现。

3、一个类继承抽象类,或者实现接口,都必须重写完他们的抽象方法,否则自己要成为抽象类或者报错!

4、都能支持的多态,都能够实现解耦合。

不同点:

1、抽象类中可以定义类的全部普通成员,接口只能定义常量,抽象方法(JDK8 新增的三种方式)

2、抽象类只能被类单继承,接口可以被类多实现。

3、一个类继承抽象类就不能再继承其他类,一个类实现了接口(还可以继承其他类或者实现其他接口)。

4、抽象类体现模板思想:更利于做父类,实现代码的复用性。 最佳实践5、接口更适合做功能的解耦合:解耦合性更强更灵活。 最佳实践

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值