>  기사  >  Java  >  Java 인터페이스를 이해하도록 합니다(자세한 예).

Java 인터페이스를 이해하도록 합니다(자세한 예).

WBOY
WBOY앞으로
2022-04-19 17:55:003734검색

이 글에서는 인터페이스의 개념과 몇 가지 지식 요약, 문법 규칙, 인터페이스의 사용, 인터페이스의 특성 등 인터페이스와 관련된 문제를 주로 소개하는 java에 대한 관련 지식을 제공합니다. 함께 살펴보겠습니다. 모두에게 도움이 되기를 바랍니다.

Java 인터페이스를 이해하도록 합니다(자세한 예).

추천 학습: "java 비디오 튜토리얼"

Interface

한 장의 그림 흐름
Java 인터페이스를 이해하도록 합니다(자세한 예).

인터페이스의 개념과 몇 가지 지식 포인트 요약

Interface ( 영어: 인터페이스 ), JAVA 프로그래밍 언어에서는 추상 유형이며 추상 메소드의 모음은 일반적으로 인터페이스로 선언됩니다. 클래스는 인터페이스를 상속하여 인터페이스의 추상 메서드를 상속합니다.
인터페이스는 클래스가 아닙니다 인터페이스를 작성하는 방법은 클래스와 매우 유사하지만 서로 다른 개념에 속합니다. 클래스는 개체의 속성과 메서드를 설명합니다. 인터페이스에는 클래스에서 구현할 메서드 가 포함되어 있습니다. 인터페이스를 구현하는 클래스가 추상 클래스가 아닌 한,
그렇지 않은 경우 클래스는 인터페이스의 모든 메서드를 정의해야 합니다 .
인터페이스는 인스턴스화할 수 없지만 구현할 수는 있습니다. 인터페이스를 구현하는 클래스는 인터페이스에 설명된 모든 메서드를 구현해야 하며, 그렇지 않으면 추상 클래스로 선언해야 합니다. 또한 Java에서는 인터페이스 유형을 사용하여 변수를 선언할 수 있습니다. 이 유형은 널 포인터가 될 수도 있고 이 인터페이스를 구현하는 객체에 바인딩될 수도 있습니다. 인터페이스와 클래스의 유사점

.Java로 끝나는 파일에는 여러 개의

인터페이스 파일이 있을 수 있으며, 파일 이름은 인터페이스 이름을 사용합니다.
    인터페이스의 바이트코드 파일은 .class에 저장됩니다. 파일 끝의
  • 인터페이스에 해당하는 바이트 코드 파일은 패키지 이름과 일치하는 디렉터리 구조에 있어야 합니다
  • 인터페이스와 클래스의 차이점
인터페이스는 객체를 인스턴스화하는 데 사용할 수 없습니다.

인터페이스는 구조 없음 메소드
    인터페이스의 모든 메소드는 추상 메소드여야 합니다. Java 8 이후에는 default 키워드로 수정된 비추상 메소드를 인터페이스에서 사용할 수 있습니다.
  • 인터페이스는 정적 변수와 최종 변수를 제외하고 멤버 변수를 포함할 수 없습니다. 인터페이스가 클래스에 의해 상속된다는 개념은 정확히 말하면 클래스에 의해 구현되어야 합니다
  • 인터페이스는 우리가 다중 상속이라고 부르는 것을 실현할 수 있습니다
  • 인터페이스의 일부 특징
  • 인터페이스의 모든 메소드는 또한 암시적으로 추상이므로 인터페이스의 메서드는 암시적으로 공용 추상으로 지정됩니다(공용 추상만 가능하며 다른 수정자는 오류를 보고합니다)
인터페이스에는 변수가 포함되어 있지만 인터페이스의 변수는 암시적으로 공용 정적으로 지정됩니다. 최종 변수(공개만 가능하며 비공개로 수정하면 컴파일 오류가 보고됨)

인터페이스의 메서드는 인터페이스에서 구현할 수 없습니다. 인터페이스의 메서드는 인터페이스를 구현하는 클래스에서만 구현할 수 있습니다.
  • 추상 클래스와 인터페이스의 차이점
  • JDK1.8 이전에는 다음과 같은 차이점이 있었습니다.
추상 클래스의 메서드는 특정 실행문, 즉 특정 기능을 구현할 수 있는 메서드 본문을 가질 수 있습니다. 하지만 인터페이스의 메서드는 그럴 수 없습니다(예:
System .out.println("I'm super corn!!");

)

추상 클래스의 멤버 변수는

다양한 유형
일 수 있지만 멤버 변수는
    다양한 유형
  • 일 수 있습니다. 인터페이스에는 public static final유형만 포함될 수 있습니다.
  • 인터페이스에는 정적 코드 블록과 정적 메서드(정적으로 수정된 메서드) 사용이 포함될 수 없지만 추상 클래스에는 정적 코드 블록과 정적 메서드A 클래스만 포함될 수 있습니다. 하나의 추상 클래스를 상속하지만 클래스는 여러 인터페이스를 구현할 수 있습니다
  • 그러면 여기서 주의해야 할 점은 다음과 같습니다.
  • JDK1.8 이후 인터페이스는 정적 메서드와 메서드 본문을 포함할 수 있으며 다음을 포함할 수 있습니다. 이 메소드를 "기본 메소드"라고 합니다. 이 메소드는 기본 키워드를 사용하여 수정합니다.
JDK1.9 이후에는 메소드를 비공개로 정의할 수 있으므로 재사용되는 특정 코드는 해당 메소드를 노출하지 않습니다.


추상 클래스의 의미는 컴파일러가 더 나은 검증을 위해 일반적으로 추상 클래스를 직접 사용하지 않고 해당 하위 클래스를 사용하도록 허용하는 것입니다. 실수로 추상 클래스를 통해 객체를 생성하면 컴파일러가 제때에 알려줍니다.
주의 사항: 위 내용을 대략적으로 한 번씩 읽어보시면 이해가 안 되셔도 상관없습니다. 그러면 아래에서 하나씩 설명드리겠습니다. 큰 꿈에서 깨어난 듯한 기분이 들 거예요


실생활에서 인터페이스란 무엇일까요? 노트북의 USB 포트, 전원 소켓 등이 될 수 있습니다.
Java 인터페이스를 이해하도록 합니다(자세한 예).
Java 인터페이스를 이해하도록 합니다(자세한 예).
그런 다음 이러한 인터페이스는 구현 및 사용 표준 측면에서도 다릅니다

  • 컴퓨터의 USB 포트에 연결할 수 있습니다. : U 디스크, 마우스, 키보드... USB 프로토콜을 준수하는 모든 장치
  • 전원 콘센트 잭에 연결할 수 있습니다: 컴퓨터, TV, 밥솥... 사양을 준수하는 모든 장치

우리는 위의 예에서 볼 수 있습니다.인터페이스는 공개 행동 규범입니다. 표준은 표준을 구현할 때 이를 준수하는 한 모든 사람이 보편적으로 사용할 수 있습니다. Java에서 인터페이스는 다음과 같이 볼 수 있습니다. 참조 데이터 유형인 여러 클래스에 대한 공통 사양

문법 규칙

인터페이스의 정의 형식은 기본적으로 클래스 정의 형식과 동일합니다. class 키워드와 인터페이스 키워드는 인터페이스를 정의합니다.

public interface 接口名称{
    //抽象方法
    public abstract void method1();
    //public abstract是固定搭配,可以不写
    public void method2();
    abstract void method3();
    void method4();
    
    //注意:在接口中上述的写法都是抽象方法,所以method4这样写代码更整洁}

팁:

  1. 인터페이스를 생성할 때 인터페이스 이름은 일반적으로 대문자 I(read ai)로 시작합니다.
  2. 인터페이스 이름 지정은 일반적으로 형용사 품사가 포함된 단어를 사용합니다.
  3. 에 동의 Alibaba Coding Standard, 인터페이스의 메서드 및 코드를 깔끔하게 유지하려면 속성에 수정자를 추가하지 마세요.

인터페이스 사용

인터페이스는 직접 인스턴스화하고 사용할 수 없습니다. 그리고 인터페이스

public class 类名称 implements 接口名称{
    //...}

에서 모든 추상 메소드를 구현합니다. 참고: 하위 클래스와 상위 클래스 간의 상속 관계는 확장이고, 클래스와 인터페이스 간의 구현 관계는 구현입니다.

USB 마우스와 USB 키보드의 클래스와 인터페이스는 노트북에서 기능을 구현하는 데 사용됩니다.

  1. USB 인터페이스: 장치를 열고 닫는 기능 포함
  2. 노트북 클래스: 켜고 끄는 기능 포함 USB 장치 사용
  3. Mouse 클래스: USB 인터페이스 구현 및 클릭 기능 포함
  4. Keyboard 클래스: USB 인터페이스 구현 및 입력 기능
//USB接口public interface USB{
    void openDevice();
    void closeDevice();}//鼠标类,实现USB接口public class Mouse implements USB{
    @Override
    public void openDevice(){
        System.out.println("打开鼠标");
    }
    
    @Override
    public void closeDevice(){
        System.out.println("关闭鼠标");
    }
    public void click(){
        System.out.println("鼠标点击");
    }}//键盘类,实现USB接口public class KeyBoard implements USB {
    @Override
    public void openDevice(){
        System.out.println("打开键盘");
    }
    
    @Override
    public void closeDevice(){
        System.out.println("关闭键盘");
    }
    
    public void inPut(){
        System.out.println("键盘输入");
    }}//笔记本类:使用USB设备public class Computer {
    public void powerOn(){
        System.out.println("打开笔记本电脑");
    }
    
    public void powerOff(){
        System.out.println("关闭笔记本电脑");
    }
    public void useDevice(USB usb){
        usb.openDevice();
        if(usb instanceof Mouse){
            Mouse mouse = (Mouse)usb;
            mouse.click();
        }else if(usb instanceof KeyBoard){
            KeyBoard keyBoard = (KeyBoard)usb;
            keyBoard.inPut();
        }
        usb.closeDevice();
    }}//测试类:public class TestUSB{
    public static void main(String[] args){
        Computer computer = new Computer();
        computer.powerOn();
   
    //使用鼠标设备
    computer.useDevice(new Mouse());
    
    //使用键盘设备
    computer.useDevice(new KeyBoard());
    
    computer.powerOff();
    }}

Output:
Java 인터페이스를 이해하도록 합니다(자세한 예).

instanceof

위의 코드 예에서 ,instanceof가 언급되어 있는데, 파트너가 잘 이해하지 못하는 부분이 있을 수 있습니다.이전 블로그에서 소개한 적이 있는데 여기서 다시 설명하겠습니다. Instanceof는 Java에서 예약된 키워드입니다. 오른쪽은 클래스이고 반환 유형은 Boolean 유형입니다.
구체적인 기능은 왼쪽 개체가 오른쪽 클래스 또는 오른쪽 클래스의 하위 클래스에서 생성된 인스턴스화된 개체인지 테스트하는 것입니다.
그렇다면 true를 반환하고, 그렇지 않으면 false를 반환합니다.

[instanceof 사용에 대한 참고 사항 ] 기존 상속 관계 , 그리고 나서 instanceof 사용(인터페이스 구현 포함)이 있습니다.

【instanceof 응용 프로그램 시나리오】 객체의 강제 유형 변환을 사용해야 하는 경우 인스턴스of를 사용해야 합니다. 판사

인터페이스의 특징

    인터페이스 유형은 참조 유형이지만 인터페이스의 객체를 직접 새로 만들 수는 없습니다.
  1. public class TestUSB {
        public static void main(String[] args){
            USB usb = new USB();
        }}//编译会出错:USB是抽象的,无法实例化

Java 인터페이스를 이해하도록 합니다(자세한 예).

    인터페이스의 모든 메소드는 공용 추상 메소드입니다. 인터페이스의 메소드는 암시적으로 public abstract로 지정됩니다(public abstract만 가능하며 다른 수정자는 오류를 보고합니다)
  1. public interface USB {
        //编译出错:此处不允许使用修饰符private
        //或者是java: 缺少方法主体, 或声明抽象
        private void openDevice();
        void closeDevice();
        //不同JDK版本编译器的标准是不一样的,报错也是不一样的}
    인터페이스의 메소드는 인터페이스에서 구현할 수 없으며 다음을 수행하는 클래스에 의해서만 구현될 수 있습니다. 인터페이스를 구현합니다
  1. public interface USB {
        void openDevice();
        
        //编译失败:因为接口中的方法默认为抽象方法
        //Error:接口抽象方法不能带有主体}

Java 인터페이스를 이해하도록 합니다(자세한 예).하지만 여기에 기본값을 추가하면 메소드 본문을 구현할 수 있습니다.

Java 인터페이스를 이해하도록 합니다(자세한 예).

    인터페이스에서 메서드를 재정의하는 경우 기본값을 액세스 권한 수정으로 사용할 수 없습니다.
  1. public interface USB {void openDevice();//默认为publicvoid closeDevice();//默认为public}public class Mouse implements USB {
        @Override
        void openDevice(){
            System.out.println("打开鼠标");
        }
        
        //...}//这里编译会报错,重写USB中的openDevice方法时,不能使用默认修饰符

Java 인터페이스를 이해하도록 합니다(자세한 예).이 인터페이스를 구현하려면 이 인터페이스를 재정의하는 메서드의 액세스 제한 수정자 범위가 이전 인터페이스보다 큽니다. 인터페이스

    인터페이스는 변수를 포함할 수 있지만 인터페이스의 변수는 컴파일러에 의해
  1. public static finalvariables
  2. public interface USB {
        double brand = 3.0;//默认为:final public static修饰
        void openDevice();
        void closeDevice();}public class TestUSB {
        public static void main(String[] args){
            System.out.println(USB.brand);
            //可以直接通过接口名访问,说明变量时静态的
            
            //下面写法会报错 Java:无法为最终变量brand分配值
            USB.brand = 2.0;
            //说明brand具有final属性
        }}

Java 인터페이스를 이해하도록 합니다(자세한 예).

    으로 자동 및 암시적으로 지정됩니다. 인터페이스
  1. public interface USB {
        public USB(){
        
        }//编译失败
        
        {
        
        }//编译失败
        
        void openDevice();
        void closeDevice();}

Java 인터페이스를 이해하도록 합니다(자세한 예).

  1. 接口虽然不是类,但是接口编译完成之后的字节码文件的后缀格式也是.class
  2. 如果类没有实现接口中的所有抽象方法,则类必须设置为抽象类
  3. JDK8中规定了接口中可以包含上面所说的default方法

实现多个接口

在Java中,类和类之间是单继承的,一个类只能由一个父类,即Java中不支持多继承,但是一个类可以实现多个接口。下面用代码来演示

public class Animal {
    protected String name;
    
    public Animal(String name){
        this.name = name;
    }}

然后我们再写一组接口,分别来表示“会飞的”“会跑的”“会游泳的”.

public interface IFlying {
    void fly();}public interface IRunning {
    void run();}public interface ISwimming {
    void swim();}

Java 인터페이스를 이해하도록 합니다(자세한 예).
那么接下来我们创建几个具体的动物类来接受并实现这些接口
比如,猫会跑

public class Cat extends Animal implements IRunning{
    public Cat(String name) {
        super(name);
    }
    
    @Override
    public void run() {
        System.out.println("小猫"+this.name+"正在跑");
    }}

鱼会游泳

public class Fish extends Animal implements ISwimming{
    public Fish(String name){
     super(name);   
    }
    
    @Override
    public void swim() {
        System.out.println("小鱼"+this.name+"正在游泳");
    }}

而青蛙即会跑又会游泳

public class Frog extends Animal implements IRunning,ISwimming{
    public Frog(String name){
        super(name);
    }
    
    @Override
    public void run() {
        System.out.println("青蛙"+this.name+"正在跑");
    }

    @Override
    public void swim() {
        System.out.println("青蛙"+this.name+"正在游泳");
    }}

注意:一个类实现多个接口的时候,每个接口中的抽象方法都要去实现,除非类用abstract修饰,为抽象类

提示IDEA中使用ctrl + i 可以快速实现接口

还有一种动物水陆空三栖,它是大白鹅

public class Goose extends Animal implements IRunning,ISwimming,IFlying{
    public Goose(String name) {
        super(name);
    }

    @Override
    public void fly() {
        System.out.println(this.name+"正在飞");
    }

    @Override
    public void run() {
        System.out.println(this.name+"正在跑");
    }

    @Override
    public void swim() {
        System.out.println(this.name+"正在漂在水上");
    }}

这段代码展现了Java面向对象编程中最常见的用法:一个类继承了一个父类,然后同时实现多个接口
继承表达的含义是is-a,而接口表达的含义是具有xxx的特性

猫是一种动物,具有会跑的特性
青蛙是一种动物,即能跑也能有用
大白鹅也是一种动物,技能跑,也能游,还能飞

有了接口之后,类的使用者就不需要去关注具体的类的属性是否符合,而只需要关心某个类是否具有某个特性/功能,如果有,就可以实现对应的接口
那么我们现在实现一个走路的方法

public class TestDemo1 {
    public static void walk(IRunning iRunning){
        System.out.println("我带着小伙伴去散步");
        iRunning.run();
    }

    public static void main(String[] args) {
        Cat cat = new Cat("小猫");
        walk(cat);
        
        Frog frog = new Frog("小青蛙");
        walk(frog);
    }}

输出结果
Java 인터페이스를 이해하도록 합니다(자세한 예).
只要是会跑的,带有跑这个属性特征的,都可以接受相应的对象

public class Robot implements IRunning{
    private String name;
    public Robot(String name){
        this.name = name;
    }
    @Override
    public void run() {
        System.out.println(this.name+"正在用轮子跑");
    }

    public static void main(String[] args) {
        Robot robot = new Robot("机器人");
        walk(robot);
    }}

Java 인터페이스를 이해하도록 합니다(자세한 예).
Java 인터페이스를 이해하도록 합니다(자세한 예).
故输出结果为
Java 인터페이스를 이해하도록 합니다(자세한 예).

接口之间的继承

在Java中,类和类之间是单继承的,一个类可以实现多个接口,接口与接口之间可以多继承。
即:用接口可以达到多继承的目的
接口可以继承一个接口,达到复用的效果。这里使用extends关键字

interface IRunning {
    void run();}interface ISwimming {
    void swim();}//两栖的动物,即能跑,也能游泳interface IAmphibious extends IRunning ISwimming {}class Frog implements IAmphibious {
    ...}

通过接口继承创建一个新的接口IAmphibious表示“两栖的”。
创建的Frog类就实现了这个两栖的接口

接口之间的继承就相当于把多个接口合并到了一起

接口使用的例子

我们在之前的数组中讲解过给数组排序,那么我们该如何给对象数组排序呢?
首先我们定义一个Student的类,然后重写一下String方法

public class Student {
    private String name;
    private int score;
    public Student(String name,int score){
        this.name = name;
        this.score = score;
    }

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

我们再给定一个学生对象数组,根据这个对象数组中的元素进行排序
这里我们按照分数降序排序

public class Student {
    private String name;
    private int score;
    public Student(String name,int score){
        this.name = name;
        this.score = score;
    }

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

    public static void main(String[] args) {
        Student[] students = new Student[]{
                new Student("A",95),
                new Student("B",96), 
                new Student("C",97),
                new Student("D",98),
        };
    }}

那么按照我们之前的理解,数组中有一个可以供我们使用的sort方法,我们能否直接使用呢?

Arrays.sort(students);System.out.println(students);//运行结果:Exception in thread "main" java.lang.ClassCastException: class ClassArray.Student cannot be cast to class java.lang.Comparable (ClassArray.Student is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
	at java.base/java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
	at java.base/java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
	at java.base/java.util.Arrays.sort(Arrays.java:1041)
	at ClassArray.Student.main(Student.java:36)

Java 인터페이스를 이해하도록 합니다(자세한 예).
我们可以看到这里程序报错了,这里的意思是Student并没有实现Comparable的接口
那么这里的sort是进行普通数字的比较,大小关系明确,而我们指定的是两个学生对象的引用变量,这样的大小关系的指定是错误的,我们需要额外去人为规定对象中的比较元素
那么怎么实现呢?

我们可以用Student类实现Comparable接口,并实现其中的compareTo方法

public class Student implements Comparable<student>{
    private String name;
    private int score;

    public Student(String name,int score){
        this.name = name;
        this.score = score;
    }

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

    @Override
    public int compareTo(Student o) {
        if (this.score>o.score){
            return -1;//      如果当前对象应排在参数对象之前,则返回小于0的数字
        } else if(this.score<o.score><p>那么我们在这里重写了compareTo的方法,自己定义了比较的规则,我们就自己再去写一个sort的方法,去调用这个compareTo方法,真正意义上实现对 对象数组的排序<br>我们使用冒泡排序法</p>
<pre class="brush:php;toolbar:false">    public static void sort(Comparable[] array){//        这里要注意,虽然接口不能实例化对象,//        但是接口类型的引用变量可以指向它的实现类对象//        这里的实现类对象就是实现了这个接口的对象//        例如Comparable[] comparable = new Student[3];//        所以这里的参数就可以用Comparable[] array来接收
        for (int bound = 0;bound<array.length>bound;cur--){
                if (array[cur-1].compareTo(array[cur])>0){
                    //这里就说明顺序不符合要求,交换两个变量的位置
                    Comparable tmp = array[cur-1];
                    array[cur-1] = array[cur];
                    array[cur] = tmp;
                }
            }
    }}</array.length>

sort方法写好了,我们写一个main函数来测试一下

    public static void main(String[] args) {
        Student[] students = new Student[]{
                new Student("A",95),
                new Student("B",91),
                new Student("C",97),
                new Student("D",95),
        };
        System.out.println("sort前:"+Arrays.toString(students));
        sort(students);
        System.out.println("sort后:"+Arrays.toString(students));
    }

运行结果

E:\develop\Java\jdk-11\bin\java.exe "-javaagent:E:\IDEA\IntelliJ IDEA Community Edition 2021.3.2\lib\idea_rt.jar=65257:E:\IDEA\IntelliJ IDEA Community Edition 2021.3.2\bin" -Dfile.encoding=UTF-8 -classpath E:\JAVAcode\gyljava\Interface\out\production\Interface ClassArray.Studentsort前:[Student{name='A', score=95}, Student{name='B', score=91}, Student{name='C', score=97}, Student{name='D', score=95}]sort后:[Student{name='C', score=97}, Student{name='A', score=95}, Student{name='D', score=95}, Student{name='B', score=91}]

那么我们如果想要按照名字排序呢?也是可以的

import java.util.Arrays;import java.util.Comparator;/**
 * Created with IntelliJ IDEA.
 * Description: Hello,I would appreciate your comments~
 * User:Gremmie
 * Date: -04-13
 * Destination:利用Comparable的接口实现对 对象数组 选择性排序的功能
 */class Student implements Comparable<student>{
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

    @Override
    public int compareTo(Student o) {
        return this.name.compareTo(o.name);
    }}class AgeComparator implements Comparator<student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age-o2.age;
    }}class NameComparator implements Comparator<student> {

    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }}public class TestDemo {

    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("zhangsan",19);
        students[1] = new Student("lisi",8);
        students[2] = new Student("abc",78);
        AgeComparator ageComparator = new AgeComparator();
        NameComparator nameComparator = new NameComparator();
        
        
        //这里的方法sort是Array里面自带的,非常方便,
        //只需将我们写好的比较器传过去就好了
        System.out.println("排序前:"+Arrays.toString(students));
        Arrays.sort(students,nameComparator);
        System.out.println("排序后:"+Arrays.toString(students));
        Comparable<student>[] studentComparable =students;
    }

    public static void main2(String[] args) {
        /*Student students1 = new Student("zhangsan",19);
        Student students2 = new Student("abc",78);
        if(students2.compareTo(students1) > 0) {
            System.out.println("fafaa");
        }*/


    }
    public static void main1(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("zhangsan",19);
        students[1] = new Student("lisi",8);
        students[2] = new Student("abc",78);
        System.out.println("排序前:"+Arrays.toString(students));
        Arrays.sort(students);
        System.out.println("排序后:"+Arrays.toString(students));
    }}</student></student></student></student>

Clonable接口以及深拷贝

其作用如其名,是用来进行克隆的,Clonable是个很有用的接口。
Object类中存在一个clone方法,调用这个方法可以创建出一个对象,实现“拷贝”。
但是我们想要合法调用clone方法,就要先实现Clonable接口,
否则就会抛出CloneNotSupportedException异常

/**
 * Created with IntelliJ IDEA.
 * Description: Hello,I would appreciate your comments~
 * User:Gremmie
 * Date: -04-13
 * Destination:利用Clonable的接口实现clone方法,克隆含对象的对象
 */class Money implements Cloneable{
    public double money = 19.9;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }}class Person implements Cloneable{
    public int id = 1234;
    public Money m = new Money();

    @Override
    public String toString() {
        return "Person{" +
                "id='" + id + '\'' +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();
        tmp.m = (Money) this.m.clone();
        return tmp;
        //return super.clone();
    }}public class TestDemo {

    public static void main(String[] args) {
        Object o = new Person();

        Object o2 = new Money();


    }

    public static void main1(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person)person1.clone();
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        System.out.println("=========================");
        person2.m.money = 99.99;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }}

我们如果只是通过clone,那么就只是拷贝了Person的对象,但是Person中的money对象我们并没有拷贝下来,只是单纯拷贝下来一个地址,那么我们在这里就要进行深拷贝,讲Money类也接受Clonable接口,这样在调用clone方法的时候,money也会进行克隆

推荐学习:《java视频教程

위 내용은 Java 인터페이스를 이해하도록 합니다(자세한 예).의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제