8 面向对象编程

8.5. final 关键字

8.5.1 基本介绍

final 中文意思:最后的, 最终的.

final 可以修饰类、属性、方法和局部变量.

在某些情况下,程序员可能有以下需求, 就会使用到final:

    1. 当不希望类被继承时,可以用final修饰.【案例演示】
    1. 当不希望父类的某个方法被子类覆盖/重写(override)时,可以用final关键字修饰。【案例演示:访问修饰符 final 返回类型 方法名 】
    1. 当不希望类的的某个属性的值被修改,可以用final修饰.【案例演示: public final double TAX_RATE=0.08】
    1. 当不希望某个局部变量被修改, 可以使用final修饰【案例演示: final double TAX_RATE=0.08 】
public class Final01 {
public static void main(String[] args) {
E e = new E();
// e.TAX_RATE = 0.09; // 编译错误,不能修改final属性的值
}
} // 如果我们要求A类不能被其他类继承,可以使用final修饰A类
final class A { } // class B extends A {} // 编译错误,不能继承final类 class C {
// 如果我们要求hi不能被子类重写,可以使用final修饰hi方法
public final void hi() {}
} class D extends C {
// 编译错误,不能重写final方法
/*
@Override
public void hi() {
System.out.println("重写了 C 类的 hi 方法..");
}
*/
} // 当不希望类的某个属性的值被修改,可以用final修饰
class E {
public final double TAX_RATE = 0.08; // 常量
} // 当不希望某个局部变量被修改,可以使用final修饰
class F {
public void cry() {
// 这时,NUM也称为局部常量
final double NUM = 0.01;
// NUM = 0.9; // 编译错误,不能修改final局部变量的值
System.out.println("NUM=" + NUM);
}
}

8.5.2 final 使用注意事项和细节讨论

    1. final修饰的属性又叫常量,一般用XX_XX_XX来命名
    1. final修饰的属性在定义时,必须赋初值,并且以后不能再修改,赋值可以在如下位置之一【选择一个位置赋初值即可】:

      ① 定义时:如public final double TAX_RATE=0.08;

      ② 在构造器中

      ③ 在代码块中。
    1. 如果final修饰的属性是静态的,则初始化的位置只能是

      ① 定义时 ② 在静态代码块 不能在构造器中赋值。
    1. final类不能继承,但是可以实例化对象。[A2类]
    1. 如果类不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承。[A3类]
    public class FinalDetail01 {
    public static void main(String[] args) {
    CC cc = new CC(); // 修正了变量名的语法错误
    new EE().cal();
    }
    } class AA {
    /*
    1. 定义时:如 public final double TAX_RATE=0.08;
    2. 在构造器中
    3. 在代码块中
    */
    public final double TAX_RATE = 0.08; // 1.定义时赋值 public final double TAX_RATE2;
    public final double TAX_RATE3; public AA() { // 构造器中赋值
    TAX_RATE2 = 1.1;
    } { // 在代码块中赋值
    TAX_RATE3 = 8.8;
    }
    } class BB {
    /*
    如果final修饰的属性是静态的,则初始化的位置只能是
    1. 定义时
    2. 在静态代码块
    不能在构造器中赋值。
    */
    public static final double TAX_RATE = 99.9; // 静态常量定义时赋值
    public static final double TAX_RATE2; static { // 静态代码块中为静态常量赋值
    TAX_RATE2 = 3.3;
    }
    } // final类不能继承,但是可以实例化对象
    final class CC { } // 非final类可以被继承
    class DD {
    // final方法不能被重写,但可以被继承
    public final void cal() {
    System.out.println("cal()方法");
    }
    } // 继承DD类,可以使用父类的final方法
    class EE extends DD { }
    1. 一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法。
    1. final不能修饰构造方法(即构造器)
    1. final 和 static 往往搭配使用,效率更高,不会导致类加载.底层编译器做了优化处理。
    class Demo{
    public static final int i=16; //
    static{
    System.out.println("~666");
    }
    }
    此处若调用Demo.i 不会导致类加载故~666不会输出
    1. 包装类(Integer,Double,Float,Boolean等都是final),String也是final类。
    public class FinalDetail02 {
    public static void main(String[] args) {
    System.out.println(BBB.num); // 包装类和String是final类,不能被继承
    // 例如: class MyString extends String {} // 编译错误
    // 例如: class MyInteger extends Integer {} // 编译错误
    }
    } // final和static往往搭配使用,效率更高,不会导致类加载,底层编译器做了优化处理
    class BBB {
    public final static int num = 10000; static {
    System.out.println("BBB静态代码块被执行");
    }
    } final class AAA {
    // 一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法
    // public final void cry() {} // 这里注释掉了多余的final修饰
    }

8.6 抽象类

8.6.1 先看一个问题 Abstract01.java

public class Abstract01 {
public static void main(String[] args) {
// 抽象类不能被实例化
// Animal animal = new Animal("动物"); // 编译错误
}
}
//思考:这里eat 这里你实现了,其实没有什么意义
//即: 父类方法不确定性的问题
//===> 考虑将该方法设计为抽象(abstract)方法
//===> 所谓抽象方法就是没有实现的方法
//===> 所谓没有实现就是指,没有方法体
//===> 当一个类中存在抽象方法时,需要将该类声明为abstract类
//===> 一般来说,抽象类会被继承,有其子类来实现抽象方法
abstract class Animal {
private String name; public Animal(String name) {
this.name = name;
} // 原有的具体方法实现(已注释,因为与抽象方法冲突)
/*
public void eat() {
System.out.println("这是一个动物,但是不知道吃什么..");
}
*/ // 抽象方法:没有方法体,需要子类实现
public abstract void eat();
}

8.6.2 解决之道-抽象类快速入门

当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法, 这个方法就是抽象方法,用abstract 来修饰该类就是抽象类。

我们看看如何把Animal做成抽象类, 并让子类Cat类实现。

abstract class Animal{

String name;

int age;

abstract public void cry();

}

8.6.3 抽象类的介绍

    1. 用abstract 关键字来修饰一个类时,这个类就叫抽象类

      访问修饰符 abstract 类名{

      }
    1. 用abstract 关键字来修饰一个方法时,这个方法就是抽象方法

      访问修饰符 abstract 返回类型 方法名(参数列表);//没有方法体
    1. 抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并实现抽象类()
    1. 抽象类,是考官比较爱问的知识点, 在框架和设计模式使用较多

8.6.4 抽象类使用的注意事项和细节讨论 AbstractDetail01.java

    1. 抽象类不能被实例化 [举例]
    1. 抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法 [举例]
    1. 一旦类包含了abstract方法,则这个类必须声明为abstract [说明]
    1. abstract 只能修饰类和方法,不能修饰属性和其它的。[说明]
public class AbstractDetail01 {
public static void main(String[] args) {
// 抽象类不能被实例化
// new A(); // 编译错误
}
} // 抽象类不一定要包含abstract方法,也可以有实现的方法
abstract class A {
public void hi() {
System.out.println("hi");
}
} // 一旦类包含了abstract方法,则这个类必须声明为abstract
abstract class B {
public abstract void hi();
} // abstract只能修饰类和方法,不能修饰属性和其它元素
class C {
// public abstract int n1 = 1; // 编译错误,abstract不能修饰属性
}

8.6.5 抽象类使用的注意事项和细节讨论 AbstractDetail02.java

    1. 抽象类可以有任意成员【抽象类本质还是类】,比如:非抽象方法、构造器、静态属性等等 [举例]
    1. 抽象方法不能有主体,即不能实现.如图所示

      abstract void aaa(){}; (此处大括号上有红色叉号示意错误 )
    1. 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类。[举例 A类,B类,C类]
    1. 抽象方法不能使用private、final和static来修饰,因为这些关键字都是和重写相违背的。
    public class AbstractDetail02 {
    public static void main(String[] args) {
    System.out.println("hello");
    }
    } // 抽象方法不能使用private、final和static来修饰,因为这些关键字与重写相违背
    abstract class H {
    // 以下都是错误的抽象方法声明方式
    // private abstract void hi(); // 错误:private与重写冲突
    // final abstract void hi(); // 错误:final与重写冲突
    // static abstract void hi(); // 错误:static与重写冲突 public abstract void hi(); // 正确的抽象方法声明
    } // 如果一个类继承了抽象类,则它必须实现所有抽象方法,除非自身也声明为abstract
    abstract class E {
    public abstract void hi();
    } // F类继承了抽象类E,但没有实现抽象方法,因此自身必须声明为abstract
    abstract class F extends E {
    } // G类继承了抽象类E,必须实现所有抽象方法
    class G extends E {
    @Override
    public void hi() {
    // 实现父类的抽象方法,必须有方法体
    System.out.println("G类实现了E类的hi()方法");
    }
    } // 抽象类的本质还是类,所以可以有类的各种成员
    abstract class D {
    // 非静态属性
    public int n1 = 10;
    // 静态属性
    public static String name = "韩顺平教育"; // 非抽象方法
    public void hi() {
    System.out.println("hi");
    } // 抽象方法
    public abstract void hello(); // 静态方法
    public static void ok() {
    System.out.println("ok");
    }
    }

8.7 抽象类最佳实践-模板设计模式

8..7.1 基本介绍

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。

8.7.2 模板设计模式能解决的问题

    1. 当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
    1. 编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式。

8.7.3 最佳实践

需求

    1. 有多个类,完成不同的任务job
    1. 要求统计得到各自完成任务的时间
    1. 精确性实现 TestTemplate.java
    1. 矫情的自然浓缩

      感情的自然浓缩
  1. 先用最容易想到的方法-》代码实现
  2. 分析问题,提出使用模板设计模式
package com.ming.abstract_;

// 抽象类-模板设计模式
public abstract class Template {
// 抽象方法,由子类实现具体任务
public abstract void job(); // 模板方法,计算任务执行时间
public void calculateTime() {
// 记录开始时间
long start = System.currentTimeMillis(); job(); // 动态绑定,调用子类的实现 // 记录结束时间
long end = System.currentTimeMillis(); System.out.println("任务执行时间: " + (end - start) + " 毫秒");
}
}
package com.ming.abstract_;

public class AA extends Template {
// 实现Template的抽象方法job,完成累加任务
@Override
public void job() {
long num = 0;
for (long i = 1; i <= 800000; i++) {
num += i;
}
}
}
package com.ming.abstract_;

public class BB extends Template {
// 重写Template的job方法,完成累乘任务
@Override
public void job() {
long num = 1;
for (long i = 1; i <= 80000; i++) {
num *= i;
}
}
}
package com.ming.abstract_;

public class TestTemplate {
public static void main(String[] args) {
// 创建AA对象并计算其任务执行时间
AA aa = new AA();
aa.calculateTime(); // 利用多态调用模板方法 // 创建BB对象并计算其任务执行时间
BB bb = new BB();
bb.calculateTime();
}
}

8 面向对象编程 8.5. final 关键字 8.6 抽象类 8.7 抽象类最佳实践-模板设计模式的更多相关文章

  1. 面向对象编程(十二)——final关键字

    final关键字 Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量. 在Java中,final关键字可以用来修饰类.方法和变量(包括成员变量和 ...

  2. (五)《Java编程思想》——final关键字

    可能使用final的三种情况:数据.方法.类. 1.final数据 final 常量必须是基本类型数据,且在定义时须赋值: 一个既是static又是final的域只占据一段不能改变的存储空间,只有一份 ...

  3. JavaSE基础知识(5)—面向对象(5.7 final关键字)

    一.说明 final属于一种修饰符,可以用于修饰类和属性.方法.局部变量 二.特点 1.修饰类 该类不能被继承,如String.Integer等 2.修饰方法 该方法不能被重写 3.修饰变量(属性和局 ...

  4. Java学习之==>面向对象编程 Part2

    一.封装 封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结 ...

  5. JAVA基础知识之面向对象编程知识汇总

    JAVA基础课程部分面向对象已经学习完成,知识结构如下: 总体知识框架: 类的结构: 面向对象编程三大特征: 关键字和抽象类接口等: 常见知识汇总: 成员变量和局部变量比较 有无返回值方法比较: 权限 ...

  6. Java 编程中关于异常处理的 10 个最佳实践

    异常处理是Java 开发中的一个重要部分.它是关乎每个应用的一个非功能性需求,是为了处理任何错误状况,比如资源不可访问,非法输入,空输入等等.Java提供了几个异常处理特性,以try,catch 和 ...

  7. 面向对象编程(四)继承,概念及super关键字,final关键字,Object类常见方法

    继承 概念: ①   继承背后的思想就是基于已存在的类来构建新类; ②   当从已存在类继承时,就重用了它的方法和属性,还可以添加新的方法和属性来定制新类以应对需求; ③   当从其它类导出的类叫作子 ...

  8. 面向对象编程(十)——继承之Super关键字及内存分析

    Super关键字

  9. JAVA面向对象-----final关键字

    JAVA面向对象-–final关键字 1:定义静态方法求圆的面积 2:定义静态方法求圆的周长 3:发现方法中有重复的代码,就是PI,圆周率. 1:如果需要提高计算精度,就需要修改每个方法中圆周率. 4 ...

  10. -1-2 java 面向对象基本概念 封装继承多态 变量 this super static 静态变量 匿名对象 值传递 初始化过程 代码块 final关键字 抽象类 接口 区别 多态 包 访问权限 内部类 匿名内部类 == 与 equal

    java是纯粹的面向对象的语言 也就是万事万物皆是对象 程序是对象的集合,他们通过发送消息来相互通信 每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象 每个对象都有它的类型  也就是 ...

随机推荐

  1. 超实用!Dify调用Java的3种实现方式!

    在一些复杂的业务中,我们可能需要使用 Dify 调用外部程序(如 Java 程序),因为这样才能满足业务的特殊需求. 例如,当我们使用 Dify 实现"AI 简历自动筛选器"的时候 ...

  2. servlet 的生命周期

    1 //servlet 的生命周期 2 @WebServlet(value = "/life",name = "LifeServlet",loadOnStart ...

  3. Jenkinsfile_定义全局全量

    一.通过def定义全局变量 注意:首行def定义的变量不能使用=赋值. def var pipeline { agent any stages { stage("定义var") { ...

  4. 关于ant design pro的权限方案设计

    ​ 访问控制(Access control)是指对访问者向受保护资源进行访问操作的控制管理.该控制管理保证被授权者可访问受保护资源,未被授权者不能访问受保护资源. 现实生活中的访问控制可以由付费或者认 ...

  5. 袋鼠云数栈UI5.0焕新升级,全新设计语言DT Design,更懂视觉更懂你!

    数栈作为袋鼠云打造的一站式数据开发与治理平台,从2016年发布第⼀个版本开始,就始终坚持着以技术为核⼼.安全为底线.提效为⽬标.中台为战略的思想,坚定不移地⾛国产化信创路线,不断推进产品功能迭代.技术 ...

  6. 他来了!袋鼠云大数据基础平台EasyMR正式上线

    7月28日,在袋鼠云2022产品发布会上,袋鼠云技术负责人思枢正式宣布旗下产品「大数据基础平台EasyMR」发布. EasyMR是袋鼠云自研的大数据基础平台,提供Hadoop.Hive.Spark.T ...

  7. AI 对冲基金模拟系统

    content: AI 对冲基金模拟系统 项目概述 AI对冲基金模拟系统是一个教育研究项目,通过模拟16位著名投资策略师(包括沃伦·巴菲特.查理·芒格等)的决策过程,探索AI在金融投资领域的应用潜力. ...

  8. 性能比对 - C# 中 WaitForExit 卡死,当 Process.Start 调用 FFMPEG 解码 高清视频 时出现

    目的 这篇文章的意义,不在于解决问题本身,因为这次问题发生在一种错误的使用条件之下,但是在这个过程中发现了一些有趣的现象,有一些感悟,进行记录. 插入几句话:运行在客户端的CS架构的软件,比WBE网页 ...

  9. Idea 2021.2 破解激活

    官网下载安装 官网 启动软件->试用 (Evaluate for free) -> Evaluate,进入欢迎界面(没有试用按钮见下面常见问题) 插件(Plugins)->齿轮按钮- ...

  10. springboot~入门第二篇~页面html跳转~

    遇到的问题:按照别人的blog搭jsp页面就是html页面跳转不了,总是如图: 终于找到了一个能用的blog ,换 thymeleaf(html页面跳转)成功. 控制器代码 注意下: @Control ...