抽象类、密封类、接口

抽象类

  • 抽象类
    1.包含抽象方法的类,叫做抽象类。由abstract修饰。
    2.抽象类当中:可以有非抽象方法。
    3.抽象类不能创建实例对象。

  • 抽象方法
    1.在抽象类内部不给予实现。当有一个类,继承了当前的抽象类后,需要实现。
    2.抽象方法不能被private修饰,如果不加访问修饰限定符,默认为public。

  • 抽象类的派生类
    1.如果是普通类,那么必须实现抽象类的抽象方法。
    2.如果是抽象类,可以不实现基类的抽象方法。

  • 抽象类和普通类的区别
    1、抽象类不能被实例化。
    2、抽象方法不能被private修饰。
    3、抽象类被abstract修饰。
    4、抽象方法不能在抽象类当中实现。

如下代码为抽象类的例子:

abstract class Animals {
    public abstract void bark();
}
//派生类为普通类,必须实现基类的抽象方法
class Cat extends Animals {
    public void bark() {
        System.out.println("Cat:喵~~喵~~喵~~");
    }
}

class Dog extends Animals {
    public void bark() {
        System.out.println("Dog:汪~~汪~~汪~~");
    }
}
//派生类为抽象类,可以不实现基类的抽象方法
abstract class Pig extends Animals {
    public void fun() {
        System.out.println("abstract class Pig:fun()");
    }
}
public class TestDemo5 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.bark();//Dog:汪~~汪~~汪~~
        Cat cat = new Cat();
        cat.bark();//Cat:喵~~喵~~喵~~
    }
}

密封类

  • 密封类
    一个类被final修饰,称为密封类,为了防止有意的派生
  • 密封方法
    被final修饰的方法,不能被重写
  • 使用时应注意
    1.该类不能作为基类。
    2.派生类被final所修饰,该类也不可以作为基类。

如下代码为密封类的例子:

final class Student {
    private String grade;
    private int id;
    private String name;

    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }
}

接口

  • 接口

接口由interface定义
属性默认修饰符为public static final
方法默认修饰符为public abstract
如:

interface One {
    public static final int COUNT = 1;//修饰符为默认的,只写int COUNT即可
    public abstract void methods1();
}
  • 接口和抽象类的区别

1.接口内的方法,必须不能被实现,而抽象类可以存在非抽象方法。

2.抽象类只能继承一次,但是接口可以被实现或者继承多个。

a. 一个抽象类可以继承一个抽象父类,但是一个接口可以使用关键字
extends继承多个接口
b. 抽象类是对类整体的抽象 而接口是对行为(方法)进行抽象
c. 接口中的成员变量和成员方法默认为public static final
和public abstract
d. 抽象类当中的方法和成员变量的修饰符没有明确要求,但是抽象类当中的
方法不能用private修饰。

interface One {
    public static final int COUNT = 1;

    public abstract void methods1();
}

interface Two {
    void methods2();
}
//这样写新的接口可以不实现extends后接口的方法
interface Three extends One, Two {
    void methods3();
}
//实现接口Three
class Test implements Three {

    public void methods1() {
        System.out.println("One.methods1()");
    }

    public void methods2() {
        System.out.println("Two.methods2()");
    }

    public void methods3() {
        System.out.println("Three.methods3()");
    }
}
public class TestDemo5 {
    public static void main(String[] args) {
        Test test = new Test();
        test.methods1();//One.methods1()
        test.methods2();//Two.methods2()
        test.methods3();//Three.methods3()
        One one = test;
        one.methods1();//One.methods1()
        Two two = test;
        two.methods2();//Two.methods2()
        Three three = test;
        three.methods3();//Three.methods3()
    }
}
  • 三种接口

1.Comparator

在类外实现 int compare(T o1, T o2)方法

class Teacher {
    private int id;
    private String subject;
    private String name;

    public Teacher(int id, String subject, String name) {
        this.id = id;
        this.subject = subject;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", subject='" + subject + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

public class TestDemo4 {
    public static void main(String[] args) {
        Teacher[] teacher = new Teacher[3];
        teacher[0] = new Teacher(04, "History", "H.s");
        teacher[1] = new Teacher(02, "Math", "M.a");
        teacher[2] = new Teacher(03, "English", "E.n");
        System.out.println(Arrays.toString(teacher));
        System.out.println("========按姓名排序=========");
        Arrays.sort(teacher, new Comparator<Teacher>() {
            @Override
            public int compare(Teacher aa, Teacher bb) {     
                return aa.getName().compareTo(bb.getName());
            }
        });
        System.out.println(Arrays.toString(teacher));
        System.out.println("========按id排序=========");
        Arrays.sort(teacher, new Comparator<Teacher>() {
            @Override
            public int compare(Teacher aa, Teacher bb) {
                return (aa.getId() - bb.getId());
            }
        });
        System.out.println(Arrays.toString(teacher));
    }
}

输出结果:
在这里插入图片描述

2.Comparable

在类内实现compareTo(T o)方法

class Teacher implements Comparable <Teacher>{
    private int id;
    private String subject;
    private String name;

    public Teacher(int id, String subject, String name) {
        this.id = id;
        this.subject = subject;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", subject='" + subject + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
    @Override
    public int compareTo(Teacher aa) {
        return subject.compareTo(aa.subject);
    }
}

public class TestDemo4 {
    public static void main(String[] args) {
        Teacher[] teacher = new Teacher[3];
        teacher[0] = new Teacher(04, "History", "H.s");
        teacher[1] = new Teacher(02, "Math", "M.a");
        teacher[2] = new Teacher(03, "English", "E.n");
        Arrays.sort(teacher);
        System.out.println(Arrays.toString(teacher));
    }
}

3.Clonable

public interface Cloneable {

}

此接口在源代码中为空接口,空接口的作用是标记这个类可以进行clone,如果不实现这个接口JVM不能够识别。

实例:

class Color implements Cloneable {
    String name;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Size implements Cloneable {
    Color color;

    public Size() {
        this.color = new Color();
    }

    //重写Object的克隆方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Size size = (Size) super.clone();
        size.color = (Color) this.color.clone();
        return size;
    }
}

public class TestDemo4 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Size size = new Size();
        Size size1 = (Size) size.clone();
        System.out.println(size.color.name);
        System.out.println(size1.color.name);
        size1.color.name = "red";
        System.out.println(size.color.name);
        System.out.println(size1.color.name);
    }
}

这种clone方法为深拷贝,原因如下:

在重写的clone()方法中有以下两条语句:
Size size = (Size) super.clone();
size.color = (Color) this.color.clone();

在例子中的代码中,第一条语句将size中的元素全部克隆到了size1中,但是Size类中只有指向Color的color,所以此时两者指向的地址相同

第二条语句将color指向的地址也同样复制了,所以size和size1中元素就会指向两个地址,即深拷贝,下面的图可以辅助理解
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43289802/article/details/83689340