接口与抽象类
接口:接口不是类,是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义。
接口中所有方法自动的属于public方法,所以申明接口时,不必要提供关键字public。
接口与抽象类的区别:
1、抽象能力:接口和抽象类都可以包含抽象方法,这意味着它们都定义了一些方法但没有提供具体的实现。然而,接口中的所有方法都是抽象的,而抽象类则可以选择性地提供部分方法的实现。
2、继承关系:在Java中,一个类只能继承一个直接父类,但可以实现多个接口。这意味着接口提供了一种弥补Java单继承局限性的机制。
3、常量定义:接口中只能定义常量,且这些常量默认是public static final的,而抽象类既可以定义普通变量也可以定义常量。
4、实现细节:接口中不包含构造器,也不能包含初始化块。这意味着接口的实现者需要自行提供这些内容。相反,抽象类中的构造器和初始化块可用于完成属于抽象类的初始化工作。
接口的同名方法冲突:
/**多接口实现,调用的是实现类的方法*/
public interface Car {
default String getName() {
return "car";
}
}
public interface Color {
default String getName() {
return "color";
}
}
public class BYD implements Color,Car{
@Override
public String getName() {
return "BYD";
}
}
public class Main {
public static void main(String[] args) {
BYD b = new BYD();
System.out.println(b.getName()); // BYD
Car car = new BYD();
System.out.println(car.getName()); // BYD
}
}
继承的父类与接口的同名方法:这种情况会优先调用父类的方法。
public interface Car {
default String getName() {
return "car";
}
}
public class BYD {
public String getName() {
return "BYD";
}
}
public class Tang extends BYD implements Car{
}
public class Main {
public static void main(String[] args) {
Tang t = new Tang();
System.out.println(t.getName()); // 输出Tang
}
}
深拷贝与浅拷贝
深拷贝:创建一个新对象,属性/方法值完全相同,但底层不是同一个对象,修改拷贝对象不影响原来的对象。
浅拷贝:创建一个新对象,指向原来对象,修改新对象的属性等值会影响原来对象。
clone()方法的使用1:
class People implements Cloneable {
private int age;
private String name;
public People(){}
public People(int age, String name) {
this.age = age;
this.name = name;
}
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 static void main(String[] args) throws CloneNotSupportedException {
People p = new People(10, "James");
/**
* 浅拷贝
*/
People p2 = p;
p.setAge(20);
System.out.println("P.hash = " + System.identityHashCode(p) + " p.age = " + p.getAge() + " P2.hash = " + System.identityHashCode(p2) + " p2.age = " + p2.getAge());
//输出结果 : P.hash = 93122545 p.age = 20 P2.hash = 93122545 p2.age = 20
/**
* 深拷贝:(只能在当前类中调用clone方法,否则会报异常)
* clone()方法是属于Object类中的protected的方法, protect方法只能在同包,同类或者子类中被访问,无法被兄弟类访问。
*/
People p3 = (People) p.clone();
p3.setAge(30);
System.out.println("P.hash = " + System.identityHashCode(p) + " p.age = " + p.getAge() + " P3.hash = " + System.identityHashCode(p3) + " p3.age = " + p3.getAge());
//输出结果 P.hash = 1209271652 p.age = 20 P3.hash = 745160567 p3.age = 30
/**
* 深拷贝
*/
People p4 = new People();
BeanUtils.copyProperties(p,p4);
p4.setAge(40);
System.out.println("P.hash = " + System.identityHashCode(p) + " p.age = " + p.getAge() + " P4.hash = " + System.identityHashCode(p4) + " p4.age = " + p4.getAge());
//输出结果 P.hash = 1209271652 p.age = 20 P4.hash = 745160569 p3.age = 40
}
}
clone方法的实现2:
public class People implements Cloneable{
private int age;
private String name;
public People() {
}
// 实现Cloneable接口,重写clone方法,并放开访问权限public
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "People{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
public People(int age, String name) {
this.age = age;
this.name = name;
}
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 class Main {
public static void main(String[] args) throws CloneNotSupportedException {
People p = new People(10,"hello");
System.out.println("p = " + p.toString());
People p2 = (People) p.clone();
p2.setAge(20);
p2.setName("world");
System.out.println("p = " + p.toString());
System.out.println("p2 = " + p2.toString());
}
}
/**
* 输出结果: clone实现深拷贝
p = People{age=10, name='hello'}
p = People{age=10, name='hello'}
p2 = People{age=20, name='world'}
*/