Java多态/代码块/final关键字

多态

  • 对象具有多种形态, 对象可以存在不同的形式
  • 父类指针指向子类对象
  • 在方法调用时, 通过父类进行调用, 真正执行时, 调用的是子类方法, 这种特征我们称之为多态

🐤多态的特点

  • 把子类对象赋给父类变量
  • 在运行时期会表现出具体的子类特征
  • 调用子类的方法

  • 既然子类是一种特殊的父类
  • 那么我们可不可以认为, 狗对象/猫对象就是动物类型的对象, 对象具有多种形态,对象可以存在不同的形式

Animal.java

public class Animal {
    void eat() {
        System.out.println("动物吃东西");
    }
}

Dog.java

public class Dog extends Animal {
    void eat() {
        System.out.println("狗吃骨头");
    }
}

Cat.java

public class Cat extends Animal {
    void eat() {
        System.out.println("猫吃鱼");
    }
}

没有使用多态

public class Demo {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();

        Cat cat = new Cat();
        cat.eat();
    }
}

使用多态

public class Demo {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.eat();

        Animal cat = new Cat();
        cat.eat();
    }
}

🐸多态的作用

  • 当把不同的子类对象都当作父类类型来看待,可以屏蔽不同子类对象之间的实现差异
  • 从而写出通用的代码达到通用编程,以适应需求的不断变化

🐬多态方法调用问题

instanceof

  • 作用:判断一个对象是否是指定的类
  • 类的强制类型转换,把父类对象赋值给子类类型
  • Animal类在上面的代码块中有
public class Demo {

    static void feedAnimal(Animal anim) {
        if (anim instanceof Dog) {
            Dog dog = (Dog) anim;
            dog.eat();
        } else if (anim instanceof Cat) {
            Cat cat = (Cat) anim;
            cat.eat();
        }
    }

    public static void main(String[] args) {
        Animal dog = new Dog();
        feedAnimal(dog);

        Animal cat = new Cat();
        feedAnimal(cat);

    }
}

代码块

  • 在类中或方法当中使用{}括起来的一段代码,就称它是一个代码块

代码块分类

🐤局部代码块

  • 直接定义在方法内部的代码块,在调用方法的时候执行

🐸初始化代码块

  • 直接在类当中定义代码块
  • 初始化代码块在运行时,还是要把它放到构造方法当中

🐬静态代码块

  • 在初始化代码块前面加上一个static
  • 在加载字节码时就会自动调用
  • 在主(main)方法之前执行的。只执行一次

类加载

  • 当第一次创建该类对象的时候,加载到内存当中
  • 在加载时,会执行static代码块中的内容

🐤字段初始化问题

  • 静态字段初始化:是在静态代码块当中初始化
  • 非静态的字段初始化:它是在构造器当中做的初始化

子类构造器默认会调用父类的构造器

SuperClass.java

public class SuperClass {
    SuperClass(){
        System.out.println("构造器SuperClass");
    }
}

SubClass.java

public class SubClass extends SuperClass {

    static {
        System.out.println(1);
    }

    SubClass(){
        super();
        System.out.println(2);
    }

}

Demo.java

public class Demo {
    private static Demo demo = null;

    private SubClass subClass = null;

    static {
        demo = new Demo();
        System.out.println(3);
    }

    public Demo() {
        subClass = new SubClass();
        System.out.println(4);
    }

    public static void main(String[] args) {
        System.out.println("main");
    }
}

final

  • 继承弊端:破坏了我们的封装,它可去访问父类当中的实现细节,可以覆盖父类当中的方法
  • final作用:修饰的内容最终,不可修改的,保证数据的安全

🐤final可以修饰内容

  • 字段:不能再去修改该字段的值,就变为了常量
  • 方法:子类就能再去覆盖该父类的方法也就是不可以进行重写了
  • 类:该类就不能再去被继承

🐸注意点

  • final修饰字段时,字段是没有初始值,必须得要自己手动设置初始值
  • final修饰变量,就代表是一个常量,命令规则:所有的字母都大写例如:MAX_VALUE
  • final可以在局部代码块当中使用
  • 如果final修饰的是基本数据类型,代表值不能再去修改了
  • 如果final修饰的是一个引用类型,代表对象引用的地址不能再去修改

单例设计模式

设计模式就是之前很多程序员经常无数次的尝试,总结出来一套最佳实践(方案)

单例:一个类在内存当中只有一个对象。别人不能再去创建新的对象

饿汉模式

  1. 必须得要在该类中创建一个对象出来
  2. 私有化自己的构造器。防止外界通过构造器来创建新的对象
  3. 给外界提供一个方法,能够获取已经创建好的对象
class ToolUtil {
    private static ToolUtil instance = new ToolUtil();

    private ToolUtil() {
    }

    static public ToolUtil getInstance() {
        return instance;
    }
}

懒汉模式

  • 就是一开始不创建需要的时候在创建
  • 但是有一个问题就是线程不安全问题
  • 懒汉模式就是先不知道需不需要,等到需要的时候在创建一个,下次就不会在创建了就使用第一次创建好的
class ToolUtil {
    private static ToolUtil instance = null;

    private ToolUtil() {
    }

    static public ToolUtil getInstance() {
        if (null == instance) {
            instance = new ToolUtil();
        }
        return instance;
    }
}
posted @ 2020-08-20 23:58  BNTang  阅读(21)  评论(0)    收藏  举报