JAVASE进阶(设计模式、设计原则)(更新中...)

目录

一、注解

内置注解:JAVA中已经定义好的注解。

元注解:修饰注解的注解。

自定义注解。

二、克隆 

JAVA中对clone的实现?

浅克隆

深克隆

 那么该如何做到深克隆呢?

三、常用设计模式

        1、创建型模式

        单例模式

        工厂模式

        工厂方法模式 

        抽象工厂模式

        原型模式


一、注解

java中的注解也称标注,可以用来对类、方法、属性、参数、包等进行标注。然后让编译器或运行时其他类进行解析。完成某个功能注解也可以编译到字节码文件中。

内置注解:JAVA中已经定义好的注解。
@Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接
口中并没有该方法时,会报编译错误。
@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
@SuppressWarnings - 指示编译器去忽略注解中声明的警告。
@FunctionalInterface 用于指示被修饰的接口是函数式接口。
元注解:修饰注解的注解。
@Retention - 标识这个注解怎么保存,是只在代码中,还是编入 class 文件中,
或者是在运行时可以通过反射访问。
@Documented - 标记这些注解是否包含在用户文档中。
@Target - 标记这个注解应该是哪种 Java 成员。
@Inherited - 标记这个注解是继承于哪个注解类(默认注解并没有继承于任何
子类)
@Repeatable - 标识某注解可以在同一个声明上使用多次。
自定义注解。

二、克隆 

克隆分为浅克隆、深克隆。

JAVA中对clone的实现?

①实现Cloneable接口

②重写clone方法(Object类中的方法)

浅克隆

克隆一个对象时,如果对象中有关联关系(has-a,把一个类当作另一个类的属性),只将关联对象的地址复制过来(只拿地址)

举例:

public class CloneDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student s1=new Student();
        Address address=new Address();
        address.setAddress("江苏");
        s1.setName("Mike");
        s1.setAge(20);
        s1.setAddress(address);

        Student s2=s1.clone();
        s2.setAge(21);
        s2.setName("Amy");
        address.setAddress("陕西");
        s2.setAddress(address);
        System.out.println(s1);
        System.out.println(s2);
    }
}
public class Student implements Cloneable{
    int age;
    String name;
    Address address;

    @Override
    protected Student clone() throws CloneNotSupportedException {
        return (Student) super.clone();
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", address=" + address.address +
                '}';
    }
}

public class Address {
    String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

运行结果

JAVASE进阶(设计模式、设计原则)(更新中...)_第1张图片

这是一个浅克隆的例子, 主函数中定义了一个叫Mike的Student对象实例,Student类中有基本类型age和name,还有引用类型Address。我们在主函数中使用了Object类中的方法clone() (重写了该方法)

    @Override
    protected Student clone() throws CloneNotSupportedException {
        return (Student) super.clone();
    }

从运行结果发现基本数据类型修改不影响被克隆的对象,但是关联对象数据被修改,克隆的和被克隆的对象都被修改了。可以证明 浅克隆的定义:克隆一个对象时,如果对象中有关联关系(has-a,把一个类当作另一个类的属性),只将关联对象的地址复制过来(只拿地址)

所以浅克隆支持引用类型成员变量的复制 

并且我们发现,克隆的对象和被克隆的对象的地址不同,即使用clone()方法 会创建一个新对象,这里区别于JAVA中的引用

JAVASE进阶(设计模式、设计原则)(更新中...)_第2张图片

深克隆

克隆一个对象时,如果对象中有关联关系,将关联对象一同克隆(创建一个新的关联对象)

 那么该如何做到深克隆呢?

1、连同关联对象一同克隆,逐级克隆(层级过多会比较麻烦)

public class CloneDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student s1=new Student();
        Address address=new Address();
        address.setAddress("江苏");
        s1.setName("Mike");
        s1.setAge(20);
        s1.setAddress(address);

        Student s2=s1.clone();
        s2.setAge(21);
        s2.setName("Amy");
        address.setAddress("陕西");
        System.out.println(s1);//Mike 20 陕西
        System.out.println(s2);//Amy 21 江苏
    }
}
public class Student implements Cloneable{
    int age;
    String name;
    Address address;

    @Override
    protected Student clone() throws CloneNotSupportedException {
        Student s=(Student) super.clone();
        Address address=(Address)s.getAddress().clone();
        s.setAddress(address);
        return s;
    }
}
public class Address implements Cloneable{
    String address;

    @Override
    protected Address clone() throws CloneNotSupportedException {
        return (Address) super.clone();
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

 在Student类中再使用clone()方法克隆Address对象,并且在Address类中重写clone()方法。

运行结果

JAVASE进阶(设计模式、设计原则)(更新中...)_第3张图片

通过结果发现,改变了关联对象地址,克隆对象的地址并未改变,说明深克隆不支持引用类型成员变量的复制。 

2、序列化(对象的输入输出流)

三、常用设计模式

        1、创建型模式

         用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使 用分离”。提供了单例、原型、工厂方法、抽象工厂、建造者 5 种创建型模式。

        单例模式

        在有些系统中,为了节省内存资源、保证数据内容的一致性,对某些类要求 只能创建一个实例,这就是所谓的单例模式. 例如,Windows 中只能打开一个 任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费, 或出现各个窗口显示内容的不一致等错误。单例模式有 3 个特点: 1. 单例类只有一个实例对象; 2. 该单例对象必须由单例类自行创建; 3. 单例类对外提供一个访问该单例的全局访问点;

        工厂模式

1、简单工厂:有一个工厂类负责生产某一类产品,同一类产品具备同一个抽象父类(抽象类/接口)。将创建对象与使用对象分离(Spring框架的设计思想)。简单工厂违背了开闭原则,添加一个产品就需要修改代码。子类过多,会导致工厂类庞大

JAVASE进阶(设计模式、设计原则)(更新中...)_第4张图片

以手机工厂为例:

手机接口:

public interface Phone {
    public  void run();
}

手机工厂接口:

public interface PhoneFactory {
    void createPhone();
}

有两种品牌的手机:HUAWEI和IPhone

手机工厂,重写创建手机方法

public class PhoneFactory {
    static Phone createPhone(String name) {
        if (name.equals("HUAWEI")) {
            return (Phone) new HUAWEI();
        }else if(name.equals("IPhone")){
            return (Phone) new IPhone();
        }else {
            return null;
        }
    }
}

华为手机运行

public class HUAWEI implements Phone{

    @Override
    public void run() {
        System.out.println("使用华为手机");
    }
}

iPhone手机运行

public class IPhone implements Phone{

    @Override
    public void run() {
        System.out.println("使用苹果手机");
    }
}

主函数

public class Solution {
    public static void main(String[] args) {
        PhoneFactory huaweiFactory=new HUAWEIFactory();
        Phone huaweiPhone=new HUAWEI();
        huaweiPhone.run();

        PhoneFactory iphoneFactory=new IPhoneFactory();
        Phone iphonePhone=new IPhone();
        iphonePhone.run();
    }
}

运行结果:

JAVASE进阶(设计模式、设计原则)(更新中...)_第5张图片

        工厂方法模式 

对工厂进行抽象,一个抽象的产品对应一个抽象的工厂。一个具体的产品对应一个具体的工厂,一个具体的工厂负责生产一个具体的产品,需要扩展新产品时,只需要添加新的具体的产品类,和新的生产该产品的工厂类即可。这样就不需要修改原来的工厂,符合开闭原则。

JAVASE进阶(设计模式、设计原则)(更新中...)_第6张图片

JAVASE进阶(设计模式、设计原则)(更新中...)_第7张图片

手机接口:

public interface Phone {
    public  void run();
}

手机工厂接口:

public interface PhoneFactory {
    void createPhone();
}

有两种品牌的手机:HUAWEI和IPhone

HUAWEI手机工厂

public class HUAWEIFactory implements PhoneFactory{
    @Override
    public void createPhone() {
        new HUAWEI();
    }
}

iPhone手机工厂

public class IPhoneFactory implements PhoneFactory{
    @Override
    public void createPhone() {
        new IPhone();
    }
}

华为手机运行

public class HUAWEI implements Phone{

    @Override
    public void run() {
        System.out.println("使用华为手机");
    }
}

iPhone手机运行

public class IPhone implements Phone{

    @Override
    public void run() {
        System.out.println("使用苹果手机");
    }
}

主函数

public class Solution {
    public static void main(String[] args) {
        PhoneFactory huaweiFactory=new HUAWEIFactory();
        Phone huaweiPhone=new HUAWEI();
        huaweiPhone.run();

        PhoneFactory iphoneFactory=new IPhoneFactory();
        Phone iphonePhone=new IPhone();
        iphonePhone.run();
    }
}

运行结果:

JAVASE进阶(设计模式、设计原则)(更新中...)_第8张图片

        抽象工厂模式

抽象工厂时生产一系列产品(某公司的产品华为手机,华为汽车),在抽象工厂中定义生产不同的产品,具体工厂负责生产一个公司的一系列产品

JAVASE进阶(设计模式、设计原则)(更新中...)_第9张图片

 定义一个抽象工厂

public interface AbstractFactory {
    Car getCar();
    Phone getPhone();
}

定义 汽车接口,手机接口

public interface Phone {
    void call();
}

public interface Car {
    void run();
}

定义产品工厂

public class RedmiFactory implements AbstractFactory{
    @Override
    public Car getCar() {
       return new RedmiCar();
    }

    @Override
    public Phone getPhone() {
        return new RedmiPhone();
    }
}

产品信息

public class RedmiPhone implements Phone{
    @Override
    public void call() {
        System.out.println("红米手机,年轻人的选择");
    }
}
public class RedmiCar implements Car{

    @Override
    public void run() {
        System.out.println("米家汽车,安心可靠");
    }
}

 主函数

public class Solution {
    public static void main(String[] args) {
        AbstractFactory redmiFactory=new RedmiFactory();
        Car redmiCar=redmiFactory.getCar();
        Phone redmiPhone= redmiFactory.getPhone();
        redmiCar.run();
        redmiPhone.call();
    }
}

运行结果

JAVASE进阶(设计模式、设计原则)(更新中...)_第10张图片

        原型模式

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能(new一个对象非常昂贵)。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式之一。

你可能感兴趣的:(JAVA进阶,每日总结,JAVA,设计模式,java)