初识Java语言——抽象类和接口
一、抽象类
什么是抽象类?即包含抽象方法的类;
什么是抽象方法?即只是声明有这个方法,不去实现它。
统一用关键字abstract修饰。
抽象类也是类;
只不过它不能单独实例化一个对象;
也可以被继承;
抽象类中的抽象方法最终一定会被实现;
二、接口
什么是接口?用关键字interface修饰,为了解决类的单继承问题而引入的。
接口可以扩展,用关键字extends进行扩展。
interface A{
}
interface B{
}
interface C extends A,B{
}
接口和抽象类有相似点,即方法为抽象方法,在jdk1.8中引入被关键字default(默认访问权限)修饰的方法可以进行实现。在接口当中,成员变量皆为静态常量,即static final修饰的,且定义的同时进行初始化。
接口可以通过类来实现,通过关键字implements实现接口(就是将接口当中的抽象方法完善实现相应功能)。同时,一个类可以同时实现多个接口。
接口不能进行实例化。
接口也可以发生向上转型和动态绑定。
interface A{
}
interface B{
}
class C implements A,B{
}
注意:接口当中的方法默认是public abstract的所以可以直接声明方法返回值类型加方法名。
(一)两类常用接口
1、排序
(1)Comparable接口,通过实现接口,重写compareTo方法,使得Arrays.sort方法可以对自定义类的对象进行排序。具体排序的规则根据具体要求而定。
例:
import java.util.Arrays;
class Student implements Comparable<Student>{
public String name;
public int age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Student(){
}
public Student(String name,int age){
this.age=age;
this.name=name;
}
@Override
public int compareTo(Student o) {//重写compareTo方法
return this.age-o.age;
}
}
public class MyComparable {
public static void main(String[] args) {
Student[]stu=new Student[]{new Student("zhangsan",38),new Student("lisi",20),new Student("wangmazi",30)};
for(Student x:stu){
System.out.println(x);
}
Arrays.sort(stu);
for(Student x:stu){
System.out.println(x);
}
}
}
弊端:改变了compareTo方法,使得以后的排序方式被写死,不能随机应变。
(2)Comparator接口
通过实现Comparator接口,重写compare方法实现灵活的排序。我们只需要通过用不同的类去实现Comparator接口就可以完成相应排序功能。
import java.util.Comparator;
public class NameComparator implements Comparator <Student2>{
@Override
public int compare(Student2 o1, Student2 o2) {//重写compare方法
return o1.name.compareTo(o2.name);
}
}
上述代码就是通过姓名进行排序的类实现的接口Comparator。
import java.util.Arrays;
class Student2{
public String name;
public int age;
@Override
public String toString() {
return "Student2{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Student2(){
}
public Student2(String name,int age){
this.name=name;
this.age=age;
}
}
public class MyComparator {
public static void main(String[] args) {
Student2[]stu=new Student2[]{new Student2("zhangsan",38),new Student2("lisi",20),new Student2("wangmazi",30)};
for(Student2 x:stu) {
System.out.println(x);
}
System.out.println("===================================================");
NameComparator nameComparator=new NameComparator();
Arrays.sort(stu,nameComparator);//通过传入不同类型的实例化对象,那么排序方式也会有所不同
for(Student2 x:stu) {
System.out.println(x);
}
}
}
(二)深拷贝——Cloneable接口
这个接口是一个空接口或者说是一个标志接口,因为它的内部没有内容,它的作用就是标识当前类可以进行克隆。所以通过implements实现这个接口,重写方法clone(),并通过实例化对象去“.”我们的clone方法,再通过引用去接收,就可以完成深拷贝。
(不懂深拷贝的可以看我前面的文章,有讲解到。)
重写clone方法:
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
总代码:
class Money implements Cloneable{
public int money;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable{
public String name;
public int age;
public Money money=new Money();
public Person(String name){
this.name=name;
}
public Person(int age){
this.age=age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", money=" + money.money +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person person=(Person)super.clone();
person.money=(Money) this.money.clone();
return person;
}
}
public class TestDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Person person =new Person("zhangsan");
System.out.println(person);
Person person2=(Person)person.clone();
System.out.println(person2);
System.out.println("===============================================");
person2.age=18;
person.money.money=18;
System.out.println(person);
System.out.println(person2);
}
}
以上就是接口和抽象类的相关知识,如有不全随时欢迎讨论。