栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java基础|接口|查漏补缺|comparable接口|深浅拷贝

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java基础|接口|查漏补缺|comparable接口|深浅拷贝

  • 不能使用new实例化一个接口,但是可以声明一个接口的变量:
Comparable x;
x = new Employe(...);
  • 还可以使用instanceof检查一个对象是否实现了某个特定的接口:
if(anObject instanceof Comparable){}
  • 接口也可以继承,子接口会继承父接口的方法。

  • 接口中不能包含实例字段,但是可以包含常量。

  • 接口中的方法都会自动被声明为public,接口中的字段总是被声明为public static final

  • 一个类只能继承一个父类,但是可以实现多个接口

  • 可以为接口方法提供一个默认实现,使用default关键字

public interface Comparable {
    default int comparaTo(T other) { return 0; }    
}
  • 默认方法还可以调用其他方法
public interface Collection {
    int size();
    default boolean isEmpty() { return size()==0; }
}
  • 当默认方法发生冲突时:1、超类优先。2、类实现的两个接口有同名方法时,需要在两个方法中选择一个实现,如下:
class Student implements Person, Named {
    public String getName() { return Person.super.getName(); }
}
Comparable接口与Comparator接口

如果需要使用Arrays类的sort方法对对象数组进行排序,那么需要实现Comparable接口。
Comparable接口需要实现一个方法compareTo(),这个方法返回正值或者负值或者0。

class Employee implements Comparable {
    public int compareTo(Employee other) {
        return Double.compare(salary, other.salary);
    }
}

如上述例子实现了Comparable接口,并且使用泛型为接口提供了一个类型参数。这样Employee就可以使用sort方法进行排序。

但是有一个问题,比如像String类这样的已经实现了Comparable接口的类,如果想要修改排序的比较方法的话,我们不可能去修改String类。这种情况就可以使用Comparator接口。
可以定义一个实现了Comparator接口的类,然后将这个类作为参数传入sort方法中同样可以实现排序。

class LengthComparator implements Comparator {
    public int compare(String first, String second) {
        return first.length()-second.length();
    }
}

具体比较时可以这样操作:

Arrays.sort(friends, new LengthComparator());

可以使用lamdba表达式简化上述写法:

Arrays.sort(friends, (first, second) -> first.length()-second.length());
对象克隆(Cloneable接口)

直接为对象创建一个副本实际上只是创建了一个指向同一个对象的引用,任何一个指向这个对象的变量做出改变都会影响另一个变量。如果想要变量指向一个新的对象,可以使用clone方法。但是clone方法是Object的一个protected方法,也就是说,只有对象自己可以调用这个方法来克隆自己。
使用clone进行拷贝,实际上是对对象的每一个字段逐个的进行拷贝,如果对象的每一个字段都是不可变的对象或者是基本类型,那么这种拷贝是没问题的,拷贝的对象的字段变化不会影响原始对象。但是如果对象包含子对象的引用,而且子对象是可变的,这种情况下实际上拷贝过来的对象还是有共享的字段,这种情况拷贝对象改变内容会影响到原始对象。
对于每一个类,需要确定:
1、默认的clone方法是否满足要求。
2、是否可以在可变的子对象上调用clone来修补默认的clone方法。
3、是否不该使用clone。
实际上第三个选项是默认选项。如果想要实现1和2,需要满足:
1、实现Cloneable接口
2、重新定义clone方法,并指定public访问修饰符。

Cloneable接口是一个标记接口。标记接口中不包含任何方法;它唯一的作用是允许在类型查询中使用instanceOf。

一个例子:

class Employee implements Cloneable {
    public Employee clone() throws CloneNotSupportedException {
        Employee cloned =  (Employee) super.clone();
        cloned.hiredDay = (Date)hireDay.clone();
        return cloned;
    }
}

上面这个深拷贝的例子可以看到,实现Cloneable接口需要将clone()方法的修饰符更改为public,在clone()方法中需要对每一个可变对象字段进行拷贝。但是有一个问题是子对象的clone()方法不一定能正常工作,这时就会抛出一个CloneNotSupportedException异常。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/424909.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号