抽象类
什么是抽象类
被abstract修饰的类就是抽象类。抽象类是类的进一步抽象,抽象类中的方法可以不做具体的实现(抽象方法,由abstract修饰)。抽象类中也可以有普通方法。
抽象方法不能由static和final修饰,因为抽象方法要被子类重写。
抽象类中不一定要有抽象方法,但是有抽象方法的类一定是抽象类。
抽象类不能实例化,但可以引用其子类对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| abstract class Animal { public String name; public Animal(String name) { this.name = name; }
public abstract void eat(); } class Dog extends Animal { public Dog(String name) { super(name); }
@Override public void eat() { System.out.println(this.name+"正在吃狗粮"); } } public class Demo1 {
public static void main(String[] args) { Animal animal = new Dog("旺旺"); animal.eat(); } }
|
执行结果:旺旺正在吃狗粮
为什么需要抽象类
抽象类中的方法可以不做具体实现,为了子类能够继承该抽象类。使用抽象类能够多一层编译器校验,增加了安全性。就像常量用final修饰,不小心修改时编译器会报错提醒。
像上面的代码main方法中new Dog改成new Animal,编译器就会报错:‘Animal’ is abstract; cannot be instantiated。
接口
什么是接口
接口是多个类的公共规范,是一种引用数据类型。接口可以理解为一种功能、特性,类实现某个接口,便可以具备某种功能。
接口中的方法默认是由public abstract修饰,接口中的属性默认是public final static。建议接口中的方法和属性不加任何修饰符号, 保持代码的简洁性.
接口不能实例化。
接口中不能有静态代码块和构造方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| interface Running{ void run(); } interface Flying{ void fly(); } abstract class Animal { public String name; public Animal(String name) { this.name = name; }
public abstract void eat(); } class Dog extends Animal implements Running { public Dog(String name) { super(name); }
@Override public void eat() { System.out.println(this.name+"正在吃狗粮"); }
@Override public void run() { System.out.println(this.name+"正在扑向他的主人"); } }
class Bird extends Animal implements Flying{ public Bird(String name) { super(name); } @Override public void eat() { System.out.println(this.name+"正在觅食"); }
@Override public void fly() { System.out.println(this.name+"正在天空中自由地翱翔"); } } public class Demo1 {
public static void main(String[] args) {
Dog dog = new Dog("旺旺"); dog.eat(); dog.run(); Bird bird = new Bird("飞儿"); bird.eat(); bird.fly(); } }
|
执行结果:
旺旺正在吃狗粮
旺旺正在扑向他的主人
飞儿正在觅食
飞儿正在天空中自由地翱翔
为什么需要接口
Java不允许多重继承,通过接口可以提供多重继承的大部分好处,同时还能避免多重继承的复杂性和低效性。
接口的使用实例
Comparable接口
对数组元素按年龄排序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| import java.util.Arrays;
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.age-o.age; } } public class Compare {
public static void main(String[] args) { Student[] students = new Student[]{ new Student("panghu",20), new Student("xiaofu",18), new Student("daxiong",19), new Student("jingxiang",16) };
Arrays.sort(students); System.out.println(Arrays.toString(students)); } }
|
执行结果:
[Student{name=‘jingxiang’, age=16}, Student{name=‘xiaofu’, age=18}, Student{name=‘daxiong’, age=19}, Student{name=‘panghu’, age=20}]
上面代码有一个问题,只能按年龄排序,如果想按姓名排序就要修改compareTo方法,修改后又只能按姓名排序。有没有一种办法,可以实现按不同的属性进行排序。利用比较器可以实现该要求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| import java.util.Arrays; import java.util.Comparator;
class Student1 {
public String name; public int age;
public Student1(String name, int age) { this.name = name; this.age = age; }
@Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; }
} class AgeComparator implements Comparator<Student1> {
@Override public int compare(Student1 o1, Student1 o2) { return o1.age-o2.age; } }
class NameComparator implements Comparator<Student1> {
@Override public int compare(Student1 o1, Student1 o2) { return o1.name.compareTo(o2.name); } } public class Compare1 {
public static void main(String[] args) { Student1[] students = new Student1[]{ new Student1("panghu",20), new Student1("xiaofu",18), new Student1("daxiong",19), new Student1("jingxiang",16) }; AgeComparator ageComparator = new AgeComparator(); NameComparator nameComparator = new NameComparator(); Arrays.sort(students,ageComparator); System.out.println("按年龄"+Arrays.toString(students)); Arrays.sort(students,nameComparator); System.out.println("按姓名"+Arrays.toString(students)); } }
|
执行结果:
按年龄[Student{name=‘jingxiang’, age=16}, Student{name=‘xiaofu’, age=18}, Student{name=‘daxiong’, age=19}, Student{name=‘panghu’, age=20}]
按姓名[Student{name=‘daxiong’, age=19}, Student{name=‘jingxiang’, age=16}, Student{name=‘panghu’, age=20}, Student{name=‘xiaofu’, age=18}]
Clonable接口
实现Clonable接口需要重写Object类的clone()方法,在方法中使用super关键字调用Object类的clone()方法,然后调用该方法即可实现克隆。
- 浅拷贝:仅仅拷贝当前对象本身,不拷贝引用类型。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| class Phone{ public String phone;
} class Person implements Cloneable{ public int age; Phone p = new Phone();
@Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }
@Override public String toString() { return "Person{" + "age=" + age + ", p.phone=" + p.phone + '}'; } } public class Demo { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); person.age=20; person.p.phone="xiaomi"; Person person2 = (Person)person.clone(); person2.age=10; person2.p.phone="iphone"; System.out.println(person); System.out.println(person2); }
}
|
-
深拷贝:不仅拷贝当前对象,还拷贝其引用类型。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| class Phone implements Cloneable{ public String phone;
@Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class Person implements Cloneable{ public int age; Phone p = new Phone();
@Override protected Object clone() throws CloneNotSupportedException { Person tmp = (Person) super.clone(); tmp.p= (Phone) this.p.clone(); return tmp; }
@Override public String toString() { return "Person{" + "age=" + age + ", p.phone=" + p.phone + '}'; } } public class Demo1 { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); person.age=20;
person.p.phone="xiaomi"; Person person2 = (Person)person.clone(); person2.age=10;
person2.p.phone="iphone"; System.out.println(person); System.out.println(person2); }
}
|