• 面向对象高级


    本期对应知识库:(持续更新中!)

    面向对象高级 (yuque.com) 







    ​​​​​​​尚硅谷_宋红康_对象内存解析.pptx

    static

    适用于公用变量

    开发中,变量 经常把一些常量设置为静态static 例如 PI

    方法 经常把工具类中的方法,声明为静态方法 静态方法可以被重载,但是不能被重写

    静态方法内可以调用静态的属性或静态的方法 ,不可以调用非静态方法和属性

    是否可以从一个static方法内部发出对非static方法的调用

    只能通过对象对非静态方法调用

    在main方法中可以直接调用static方法,无需创建对象!直接调用工具类即可

    1. static String nation ;
    2. c1.nation = "china";
    3. c2.nation;
    4. // 两个打印出来是一样的
    5. //在main方法中可以直接调用static方法,无需创建对象!直接调用工具类即可
    6. class Util{
    7. static void mathUtil(){
    8. }
    9. }
    10. public static void main(String[] args) {
    11. Util.mathUtil();
    12. }

    设计模式

    经典的设计模式有23种,具体有一下处理方法:

    单例设计模式

    经典的设计模式有23种

    解决问题:在整个软件系统中,只存在当前类的唯一实例!

    一个对象实例

    所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。

    单例模式实现方式:

    饿汉式、懒汉式、枚举类等

    饿汉式(开发推荐写)
    1. class Singleton {
    2. // 1.私有化构造器
    3. private Singleton() {
    4. }
    5. // 2.内部提供一个当前类的实例
    6. // 4.此实例也必须静态化
    7. private static Singleton single = new Singleton();
    8. // 3.提供公共的静态的方法,返回当前类的对象
    9. public static Singleton getInstance() {
    10. return single;
    11. }
    12. }
    懒汉式
    1. class Singleton {
    2. // 1.私有化构造器
    3. private Singleton() {
    4. }
    5. // 2.内部提供一个当前类的实例
    6. // 4.此实例也必须静态化
    7. private static Singleton single;
    8. // 3.提供公共的静态的方法,返回当前类的对象
    9. public static Singleton getInstance() {
    10. if(single == null) {
    11. single = new Singleton();
    12. }
    13. return single;
    14. }
    15. }
    饿汉式 vs 懒汉式0

    饿汉式:

    • 特点:立即加载,即在使用类的时候已经将对象创建完毕。
    • 优点:实现起来简单;没有多线程安全问题。
    • 缺点:当类被加载的时候,会初始化static的实例,静态变量被创建并分配内存空间,从这以后,这个static的实例便一直占着这块内存,直到类被卸载时,静态变量被摧毁,并释放所占有的内存。因此在某些特定条件下会耗费内存

    懒汉式:

    • 特点:延迟加载,即在调用静态方法时实例才被创建。
    • 优点:实现起来比较简单;当类被加载的时候,static的实例未被创建并分配内存空间,当静态方法第一次被调用时,初始化实例变量,并分配内存,因此在某些特定条件下会节约内存
    • 缺点:在多线程环境中,这种实现方法是完全错误的,线程不安全,根本不能保证单例的唯一性。
      • 说明:在多线程章节,会将懒汉式改造成线程安全的模式。

    main()方法

    程序入口,普通的静态方法

    类的成员(代码块)

    类的成员有属性,方法,构造器,代码块,内部类

    只能使用static修饰

    代码块作用:用来初始化类或者对象的信息(即初始化类或者对象的成员变量)

    内部可以 声明变量、调用方法或者属性,编写输出语句等;

    静态代码块随着类的创建而运行,非静态代码块随着对象的创建而运行。因此静态代码块输出先于非静态代码块。

    1. {
    2. int a;
    3. eat();
    4. b;
    5. }
    6. static{
    7. int a;
    8. eat();
    9. b;
    10. }
    执行顺序

    final

    最终的

    final可以用来修饰变量、方法、类

    类 比如 String、StringBuffer、StringBulider类 不能被继承

    方法 比如Object类中的getClass() 不能被重写

    常量都是大写 例如PI 一旦赋值,不能被修改

    final修饰成员变量 一旦赋值,不能修改 一般使用在 显示赋值、代码块中赋值、构造器中赋值 (不能在方法中赋值)

    final修饰局部变量 一旦赋值,不能修改 一般使用在方法的形参或者方法内

    final与static搭配赋值给成员变量时,一般称此成员变量为全局变量。 比如Math中的PI

    abstract(可以理解为面向对象特征之一)

    抽象

    抽象方法使用于 一个父类不能具体 例如哺乳动物 子类是人 、猴子等

    抽象分为抽象方法和抽象类

    抽象类:被abstract修饰的类 不能被示例化(即创建对象) 子类继承后必须重写方法

    抽象方法:被abstract修饰的没有方法体的方法

    abstract不能与私有方法、静态方法、final方法和final类共存!

    1. //只有抽象类中才能有抽象方法
    2. public abstract class person(
    3. public abstract void eat()//没有方法体
    4. )

    Interface接口

    接口中的方法默认是抽象的,所以在接口中定义方法时不需要使用 abstract 关键字。

    接口属性声明必须使用public static final 修饰

    接口方法声明 抽象方法 public abstract(jdk8之前)

    静态方法 (jdk8)

    私有方法 (jdk9)

    接口不可以声明 构造器和代码块等

    接口的多态性 : 接口名 变量名 = new 实现对象;

    1. //接口的多实现弥补了单继承的局限性
    2. class A extends SuperA implements B,C{
    3. }
    4. interface Cc extends Aa,Bb{
    5. }
    区分抽象类和接口

    共性: 都可以声明抽象方法

    都不能实例化(创建对象)

    不同: 抽象类一定有构造器,接口没有构造器

    类与类之间有继承关系,类和接口之间是实现关系,接口与接口之间是多继承关系。

    匿名类

    对应视频 内部类 后面讲解

    116-面向对象(高级)-类的成员之五:内部类_哔哩哔哩_bilibili

    匿名类用于调用抽象方法和接口

    匿名类的使用 可以看成重写一个构造器

    1. class A{
    2. // public A (){}; 空参构造器
    3. // A a ;
    4. A a = new A(){//后面重写接口和抽象类的方法体即可
    5. void eat(){}
    6. };
    7. //调用方法:
    8. a.eat();
    9. // 或者
    10. new A(){
    11. //重新的方法体eat()
    12. }.eat();
    13. }
    1. //接口和抽象类调用,可以使用匿名类方法
    2. public class Test {
    3. public static void main(String[] args) {
    4. B b = new B();
    5. b.method();
    6. //匿名对象调用接口A 方法1
    7. A a = new A(){
    8. public void method(){
    9. System.out.println("override A's method");
    10. }
    11. };
    12. a.method();
    13. // 匿名对象调用接口A 方法2
    14. new A(){
    15. public void method(){
    16. System.out.println("override A's method");
    17. }
    18. }.method();
    19. } // 这是匿名类实现的 A 接口的方法
    20. }
    21. interface A{
    22. public void method();
    23. }
    24. class B implements A{
    25. public void method(){
    26. System.out.println("override A's method");
    27. }
    28. }

    内部类

    内部类可以除了用public 缺省权限修饰外,还可以用private、protected修饰,也可以使用static修饰

    1. //静态
    2. Animal.Dog dog = new Animal.Dog();
    3. //非静态
    4. Animal a1 = new Animal();//先创建外部类对象
    5. Animal.Cat cat = a1.new Cat();

    枚举类

    开发中,当需要定义一组常量时,强烈建议使用枚举类。

    1. public enum Color {
    2. RED,ORANGE,YELLOW,GREEN,CYAN,BLUE,PURPLE;
    3. }
    4. public static void main(String[] args) {
    5. System.out.println(Color.GREEN);
    6. }
    7. //枚举类的构造器默认为私有的,可以省略修饰符private
    8. //没有set方法,是因为属性用final修饰了
    9. public enum SeasonEnum {
    10. SPRING("春天","春风又绿江南岸"),
    11. SUMMER("夏天","映日荷花别样红"),
    12. AUTUMN("秋天","秋水共长天一色"),
    13. WINTER("冬天","窗含西岭千秋雪");
    14. //属性必须加 private final
    15. private final String seasonName;
    16. private final String seasonDesc;
    17. private SeasonEnum(String seasonName, String seasonDesc) {
    18. this.seasonName = seasonName;
    19. this.seasonDesc = seasonDesc;
    20. }
    21. public String getSeasonName() {
    22. return seasonName;
    23. }
    24. public String getSeasonDesc() {
    25. return seasonDesc;
    26. }
    27. }

    注解(Annotation)

    注解也可以看做是一种注释,通过使用 Annotation,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。但是,注解,不同于单行注释和多行注释。

    • 对于单行注释和多行注释是给程序员看的。
    • 而注解是可以被编译器或其他程序读取的。程序还可以根据注解的不同,做出相应的处理。
    生成文档相关的注解
    1. @author 标明开发该类模块的作者,多个作者之间使用,分割
    2. @version 标明该类模块的版本
    3. @see 参考转向,也就是相关主题
    4. @since 从哪个版本开始增加的
    5. @param 对方法中某参数的说明,如果没有参数就不能写
    6. @return 对方法返回值的说明,如果方法的返回值类型是void就不能写
    7. @exception 对方法可能抛出的异常进行说明 ,如果方法没有用throws显式抛出的异常就不能写
    在编译时进行格式检查(JDK内置的三个基本注解)

    @Override: 限定重写父类方法,该注解只能用于方法

    @Deprecated: 用于表示所修饰的元素(类,方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择

    @SuppressWarnings: 抑制编译器警告

    跟踪代码依赖性,实现替代配置文件功能
    • Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署。
    三个最基本的注解
    @Override
    • 用于检测被标记的方法为有效的重写方法,如果不是,则报编译错误!
    • 只能标记在方法上。
    • 它会被编译器程序读取。
    @Deprecated
    • 用于表示被标记的数据已经过时,不推荐使用。
    • 可以用于修饰 属性、方法、构造、类、包、局部变量、参数。
    • 它会被编译器程序读取。
    @SuppressWarnings
    • 抑制编译警告。当我们不希望看到警告信息的时候,可以使用 SuppressWarnings 注解来抑制警告信息
    • 可以用于修饰类、属性、方法、构造、局部变量、参数
    • 它会被编译器程序读取。
    • 可以指定的警告类型有(了解)
      • all,抑制所有警告
      • unchecked,抑制与未检查的作业相关的警告
      • unused,抑制与未用的程式码及停用的程式码相关的警告
      • deprecation,抑制与淘汰的相关警告
      • nls,抑制与非 nls 字串文字相关的警告
      • null,抑制与空值分析相关的警告
      • rawtypes,抑制与使用 raw 类型相关的警告
      • static-access,抑制与静态存取不正确相关的警告
      • static-method,抑制与可能宣告为 static 的方法相关的警告
      • super,抑制与置换方法相关但不含 super 呼叫的警告
      • ...

    单元测试(JUnit)

    需要导入两个jar包/或者在IDEA下AIT+ENTER下载

    JUnit4版本,要求@Test标记的方法必须满足如下要求:

    • 所在的类必须是public的,非抽象的,包含唯一的无参构造器。
    • @Test标记的方法本身必须是public,非抽象的,非静态的,void无返回值,()无参数的。
    1. package com.atguigu.junit;
    2. import org.junit.Test;
    3. public class TestJUnit {
    4. @Test
    5. public void test01(){
    6. System.out.println("TestJUnit.test01");
    7. }
    8. @Test
    9. public void test02(){
    10. System.out.println("TestJUnit.test02");
    11. }
    12. @Test
    13. public void test03(){
    14. System.out.println("TestJUnit.test03");
    15. }
    16. }
    设置执行JUnit用例时支持控制台输入

    1. 设置数据:

    默认情况下,在单元测试方法中使用Scanner时,并不能实现控制台数据的输入。需要做如下设置:

    在idea64.exe.vmoptions配置文件中加入下面一行设置,重启idea后生效。

    -Deditable.java.test.console=true

    2. 配置文件位置:

    添加完成之后,重启IDEA即可。

    3. 如果上述位置设置不成功,需要继续修改如下位置

    修改位置1:IDEA安装目录的bin目录(例如:D:\develop_tools\IDEA\IntelliJ IDEA 2022.1.2\bin)下的idea64.exe.vmoptions文件。

    修改位置2:C盘的用户目录C:\Users\用户名\AppData\Roaming\JetBrains\IntelliJIdea2022.1 下的idea64.exe.vmoptions`件。

    定义test测试方法模板

    选中自定义的模板组,点击”+”(1.Live Template)来定义模板。

    包装类

    为了使基本数据类型具有引用数据类型特征!

    自动装箱与拆箱:

    由于我们经常要做基本类型与包装类之间的转换,从JDK5.0开始,基本类型与包装类的装箱、拆箱动作可以自动完成。例如:

    1. Integer i = 4;//自动装箱。相当于Integer i = Integer.valueOf(4);
    2. i = i + 5;//等号右边:将i对象转成基本数值(自动拆箱) i.intValue() + 5;
    3. //加法运算完成后,再次装箱,把基本数值转成对象。

    注意:只能与自己对应的类型之间才能实现自动装箱与拆箱。

    1. Integer i = 1;
    2. Double d = 1;//错误的,1是int类型
    三种类型转换(基本数据类型、包装类、String类)

     

    结语

    我是南城余!欢迎关注我的博客!一同成长!

    一名从事运维开发的worker,记录分享学习。

    专注于AI,运维开发,windows Linux 系统领域的分享!

  • 相关阅读:
    Sa-Token
    前后端数据交互与HTTP协议
    PMP 11.27 考试倒计时6天!
    自考改革过渡期!广东小自考最优解只需要2门笔试
    Unittest 框架介绍及第一个demo
    linux安装jdk1.8并启动jar包(又一次配置环境,简单记录下,要是小白,刚接触,按照步骤来即可)
    PHP:异常
    有效管理token,充分发挥ChatGPT的能力
    前端策略模式:react hooks 表单验证
    音视频播放器开发——实现变速播放
  • 原文地址:https://blog.csdn.net/m0_63031112/article/details/134325865