版权声明:中华人民共和国持有版权 https://blog.csdn.net/Fly_Fly_Zhang/article/details/83629090
抽象类:包含抽象方法的类叫抽象类。抽象方法由 abstract修饰。有抽象方法的类也必须由abstract修饰。
- 抽象方法:在抽象类内部不给予实现。当有一个类,继承了当前的抽象方法后需要实现。抽象方法不能被private修饰(修饰意味着不能被别的类继承,而抽象方法又必须被继承);如果不加访问修饰符,那么必须默认为public。
abstract class Animal{
public abstract void bark();//抽象方法
}
abstract class Dog extends Animal{
public Dog(){ //构造函数
}
public void bark(){ //实现基类的抽象方法。
System.out.println();
}
}
abstract class LittleDog extends Dog{
{
System.out.println("实例代码块");
}
public void bark(){
System.out.println("复写基类");
}
}
-
抽象类的派生类:
-
如果是普通类,那么必须实现抽象类的抽象方法。
-
如果是抽象类,那么可以不实现基类的抽象方法。
-
注意:
-
抽象类当中可以有非抽象方法;
-
抽象类不能创建实例对象 。 new
-
面试问题:抽象类和普通类的区别?
-
抽象类不能被实例化。
-
抽象方法必须是public/protected/或者不写修饰
-
抽象类被abstract修饰。
-
抽象方法不能在抽象类当中实现。
密封类:被final所修饰的类就是密封类。
- 注意:
- 该类不能作用于基类,因为不能被继承。
- 就算派生类被final所修饰也不可以。(防止有意的派生,本来密封了结果又继承基类,等于没有密封)
- 密封方法:不能被重写。
接口
- 由interface定义
- 成员变量属性:默认为public static final
- 成员方法:默认为public abstract
interface A extends {
public abstract void fun();
}
interface B{
public static final int age=10;//接口里面的成员必须初始化
public abstract void fun2();
}
interface C extends A,B{ // 接口只能继承接口不能实现接口。且不能继承抽象类。
}
-
注意:接口和抽象类的区别
-
接口内的方法必须不能被实现(不能有非抽象方法),而抽象类可以有部分非抽象方法。
-
抽象类只能继承一次,但接口可以被实现或者继承多个(也就是说一个抽象类可以继承一个抽象父类,但是一个接口可以使用关键字extends 继承多个接口)。
-
抽象类是对类整体的抽象,而接口是对行为进行抽象。
-
抽象类当中方法和成员变量没有明确的要求。但是抽象类当中的方法不能是private。
-
在Java中继承只是单继承。接口是另类的多继承。
-
implements实现接口A B 接口必须实现方法。
-
interface D extends A B可以不用实现AB接口方法。但是等效于D接口中有A B D中所有的抽象方法。
四个特殊接口:
-
Cloneable:实现Clonable接口需要重写Object的Clone方法。
-
super.clone(),这个操作主要是来做一次bitwise copy( binary copy ),即浅拷贝,他会把原对象完整的拷贝过来包括其中的引用。这样会带来问题,如果里面的某个属性是个可变对象,那么原来的对象改变,克隆的对象也跟着改变。所以在调用完super.clone()后,一般还需要重新拷贝可变对象。
class Money implements Cloneable{
double money=10.0d;
@Override //重写Object的clone方法。
protected Object clone() throws CloneNotSupportedException { //抛出异常
return super.clone();//返回值为基类也就是Object
}
}
class Person5 implements Cloneable{
private String name;
Money m;
public Person5(String name ){ //构造函数;
this.name=name;
this.m=new Money();
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person5 person5=(Person5)super.clone(); //clone一个对象
person5.m=(Money)this.m.clone(); //clone这个对象的m方法
return person5;
}
}
class cloneAble2 {
public static void main(String args []) throws CloneNotSupportedException { //抛出异常
Person5 person5=new Person5("hahah"); //产生一个对象,
Person5 person51=(Person5)person5.clone(); //clone一个对象
System.out.println(person5.m.money);
System.out.println(person51.m.money);
person5.m.money=1000.0d;
System.out.println(person5.m.money);
System.out.println(person51.m.money);
}
- 面试问题:Cloneable在源码中是空接口,标记接口。请问这个空接口的设计有什么作用?
标记这个类可以进行clone,如果不实现这个接口JVM 不能识别。 - Comparable:排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序“
import java.util.Arrays;
class Students implements Comparable<Students> {
private String name;
private int age;
private double score;
public Students(String name,int age,double score){//构造函数
this.name=name;
this.age=age;
this.score=score;
}
@Override
public String toString() {
return "Students{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
@Override //调用comparable里的compareTo方法
public int compareTo(Students o) { //复写comparable
return name.compareTo(o.name); //字符串需要再次使用comparaTo方法。
return age-o.age ;//整型直接减就好
}
}
class a {
public static void main(String[] args) {
Students[] students = new Students[3]; //创建一个类类型的类数组
students[0] = new Students("gaobo", 48, 99.0);
students[1] = new Students("aangzhuo", 28, 49.0);
students[2] = new Students("yangliu", 18, 59.9);
Arrays.sort(students); //排序
System.out.println(Arrays.toString(students));
- Comparator:比较接口。Comparator是比较器,我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
class Student {
private String name;
private int age;
private double score;
public Student(String name,int age,double score) {//构造函数
this.name=name;
this.age=age;
this.score=score;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
class cloneAble {
public static void main(String[] args) {
Student[] student = new Student[3];
student[0] = new Student("gaobo", 48, 99.0);
student[1] = new Student("aangzhuo", 28, 49.0);
student[2] = new Student("yangliu", 18, 59.9);
Arrays.sort(student,new Comparator<Student>(){ //在类外调用Arrays.sort 里面的comparator 方法
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();
return (int)(o1.getScore()-o2.getScore()); //默认为int 类型,所以必须强转。
return o1.getName().compareTo(o2.getName()); //字符串排序需要用到comparaTo方法进行比较。
}
});
System.out.println(Arrays.toString(student));
}
}
- 面试问题:Comparable和Comparator区别?
- Comparable:在类内部进行重写。
- Comparator:在类外直接调用。(Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。 )