【Java语言】抽象类与接口
抽象类
抽象类:一个类中没有包含详细的信息来描述一个对象,一般抽象类都是父类而且没有描述一个具体的对象。举一个例子吧:
父类Animal中的back方法好像并没有什么实际工作,都是由 Animal的各种子类的back方法来完成的,像这种没有实际工作的方法,我们可以把它设计成一个抽象方法,包含抽象方法的类我们称为抽象类.
抽象类的语法
在Java中,被abstract修饰的类叫抽象类,在抽象类中被abstract修饰的方法叫抽象方法,抽象方法不需要写具体的代码。而且抽象类也可以写属性、普通方法和构造方法。
抽象类的特性
- 抽象类不能实例化对象,所以它的存在就是为了被继承;
- 如果一个类中含有抽象方法那么这个类一定是抽象类,但是抽象类中不一定有抽象方法 ;
- 普通类继承抽象类后,一定需要重写抽象类中的所有抽象方法;
- 抽象方法不能被final、static修饰(不能被重写),也不能被private修饰(重写需要权限更高的);
- 如果普通类C继承了抽象类B,抽象类B又继承了父类抽象类A,那么C既要继承父类又要继承父类的父类;
抽象类的作用
抽象类不实现任何工作,都是子类在完成,那么它和普通的父类有什么区别呢?其实抽象类就是为了预防错误,不让抽象类实例化对象,方便我们尽早发现问题所在。就像final一样,它的存在就是让变量成为常量不被改变。
接口
接口:在Java中,接口可以看成多个类的公共规范,是一种引用数据类型。
接口的语法
需要使用interface来定义一个接口, 其实也就是把class换成了它。而且在接口当中,成员变量默认是public static final、成员方法默认是public abstract,所以一般情况下都不写。接口当中没有普通方法。
接口的使用
接口不能直接使用,必须有一个实现类来实现该接口,而且必须实现接口的所有抽象方法。子类和父类的继承关系用extends,类和接口的实现关系用implements。
接口的特性
- 接口当中定义default、static方法是可以有具体的实现;
- 接口不能实例化对象;
- 接口也可以发生向上转型和动态绑定;
- 当一个类实现接口中的方法后,当前类中的方法不能加public;
- 接口中不能有构造方法和代码块;
- 一个类可以产生一个独立字节码(.class)文件,一个接口也可以;
实现多个接口
在Java中,继承不能是多继承(就是一个类只能继承一个父类,不能多继承父类),但是在接口中可以实现多接口(即一个类可以实现多个接口),实现多接口的话就需要把所有接口中的所有抽象方法都重写一遍。 而且也可以这样写一个类继承一个父类又实现多个接口;
接口间的继承
类与类之间单继承,接口之间可以实现多继承(即使就是一个接口可以继承多个父类的接口),也是用extends关键字来实现。 如果实现ISwimming接口的话需要重写该接口即父类接口的所有接口方法。
object类
这里使用了object类,object是所有类的祖先,所以有时候就会发生向上转型,就像下面的equals方法一样,下面的equal是想要判断两个是否相等,如果根据原来的equal方法是没有办法判断下面两个对象是否相等的,所以需要我们重新写equal方法(父类和子类有重名的方法时调用子类的方法)。
import java.util.Arrays;
//类实现接口Comparable(包里就有的接口),而这个接口编程调用compareTo方法
class Clothes implements Comparable{public String name;public int money;public Clothes(String name, int money) {this.name = name;this.money = money;}@Overridepublic String toString() {return "Clothes{" +"money=" + money +", name='" + name + '\'' +'}';}//需要重写方法实现排序public int compareTo(Object o) {Clothes s = (Clothes) o;if (this.money > s.money) {return -1;} else if (this.money < s.money) {return 1;} else {return 0;}}
}public class Test1 {public static void sort(Comparable[] array) {for (int i = 0; i < array.length; i++) {for (int j = array.length - 1; j > i; j--) {if (array[j - 1].compareTo(array[j]) < 0) {//交换两个对象的下标位置Comparable tmp = array[j - 1];array[j - 1] = array[j];array[j] = tmp;}}}}public static void main(String[] args) {Clothes[] clothes = new Clothes[]{new Clothes("上衣", 40),new Clothes("裤子", 80),new Clothes("袜子", 10),};sort(clothes);//先排序再打印System.out.println(Arrays.toString(clothes));}
}
Clonable接口和深拷贝
Object 类中存在一个clone方法, 调用这个方法可以拷贝一个对象。但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会出现异常。
“浅拷贝”
“浅拷贝”就是拷贝引用对象最近一层的对象拷贝,就比如在一个栈中开辟了一块空间,这个空间指向了一个堆区的对象A,然后这个对象有指向了一个对象B,“浅拷贝”就是把A的空间在堆区拷贝了一份,拷贝的地址改变了,但是里面的内容不变,所以它指向的还是对象B。
“深拷贝”
“深拷贝”就是将对象A、对象B都拷贝一份,B是深入的对象。这样下来就可以改变对象B中变量的值。