39-咸鱼学Java-面向对象编程核心之抽象类,密封类和接口

抽象类

abstract class Animal{
    abstract public void cry();     //抽象方法不实现
    //抽象类中可以有非抽象方法
    public void fun1()
    {
        System.out.println("Animal fun1");
    }
}
//当一个类实现某个抽象类的时候,必须实现其抽象方法
class Dog extends Animal{
    public void cry()
    {
        System.out.println("旺旺");
    }
}
//如果一个抽象类继承一个抽象类,那么可以不实现基类的抽象方法
abstract class Cat extends Animal{
}
class LittleCat extends Cat{
    //当你继承的抽象类有父类的时候,你也必须实现其父类的抽象方法
    @Override
    public void cry() {
        // TODO Auto-generated method stub

    }   
}

从上面的代码我们可以看出抽象类的大部分特点
除了上面的还有
1.抽象类不能实例化(不能new)
2.抽象类中的默认修饰符为public
3.子类必须实现抽象父类的抽象方法,如果不实现子类必须由abstract修饰(即子类必须为抽象类)

密封类

密封类及被final修饰的类,其不能被继承,而且方法不能被修改
其主要是为了防止派生。

接口

接口的作用主要是因为Java不具备多继承所以通过接口可以进行各种方法的继承。一个类可以同时实现多个接口。
1.接口中默认数据成员为 public static final
默认成员方法为 public abstract
2.接口和接口直接可以继承
interface A extends B{},相当于A扩展B
3.接口不能实现接口
Demo:

//接口A
interface A {
    public int age = 10;
    public void fun1();
}
//接口B
interface B{
    int b = 100;
    void fun2();
}
//类C实现接口A和B
class C implements A,B{
    //因为其实现了这两个接口,所以需要实现其中的所有方法
    @Override
    public void fun2() {
        // TODO Auto-generated method stub

    }

    @Override
    public void fun1() {
        // TODO Auto-generated method stub

    }

}

接口和抽象类的区别

1.接口可以被实现多个,抽象类只能继承一个
2.抽象类中可以写非抽象方法
3.接口的数据成员变量都是public static final
4.接口是对行为的一种抽象(如鸟会飞,飞机会飞,飞就是接口),抽象类本身是对类整体的抽象(猫是动物,狗也是动物,动物就是抽象类)

接口的应用

1.Cloneable

class Money implements Cloneable{
    double money = 10.0;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Money m = (Money) super.clone();
        return m;
    }

}
//Cloneable 空接口
//Cloneable 标志位 flag 如果不实现  JVM无法识别
class Person implements Cloneable{
    public String name;
    Money m;
    public Person(String name) {
        this.name = name;
        m = new Money();
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person p = (Person) super.clone();
        p.m = (Money)this.m.clone();
        return p;
    }
}

Cloneable接口主要是为了类的克隆,这样的话你的类就具有了克隆的方法,就可以通过.clone调用克隆方法,然后进行类的克隆。
测试

public static void main(String[] args) throws CloneNotSupportedException {
    Person p1 = new Person("li1");
    Person p2 = (Person) p1.clone();
    System.err.println("p1"+p1);
    System.err.println("p2"+p2);
    p1.m.money = 1000;
    System.err.println(p1.m.money);
    System.err.println(p2.m.money);
}

结果
p1time20180523.Person@1d7fbfb
p2time20180523.Person@e020c9
1000.0
10.0

可以看出其打印出来的地址不同。
注意
此接口在使用的时候,clone方法和Cloneable必须同时使用,不可单独使用,如果单独使用就会报异常,因为JVM(Java虚拟机)需要一个接口当做标志位,来判别其是否可以被克隆。

2. Comparable

此接口主要是用于比较。

class Person1 implements Comparable<Person1>{
    private String name;
    private int age;
    private double score;
    public Person1(String name, int age, double score) {
        super();
        this.name = name;
        this.age = age;
        this.score = score;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Person1 [name=" + name + ", age=" + age + ", score=" + score + "]";
    }
    @Override
    /**
     * o为待排序的
     */
    public int compareTo(Person1 o) {
        //按年龄降序
        return o.age-age;
    }

}

在类实现此接口之后就可以调用系统的排序函数进行排序。
测试

public static void main(String[] args) {
    Person1[] array = new Person1[3];
    array[0]  = new Person1("one", 10, 3);
    array[1]  = new Person1("two", 26, 2);
    array[2]  = new Person1("three", 3, 1);
    Arrays.sort(array);
    System.out.println(Arrays.toString(array));
}

结果[Person1 [name=two, age=26, score=2.0], Person1 [name=one, age=10, score=3.0], Person1 [name=three, age=3, score=1.0]]
在Arrays.sort函数中
这里写图片描述
此函数 就是为了进行对象排序所准备的。

3.Comparator

Comparator为比较器,其比Comparable灵活,使用方式为

public static void main(String[] args) {
    Person1[] array = new Person1[3];
    array[0]  = new Person1("one", 10, 3);
    array[1]  = new Person1("two", 26, 2);
    array[2]  = new Person1("three", 3, 1);
    //按照用户自己的想法进行排序
    Arrays.sort(array,new Comparator<Person1>() {

        @Override
        public int compare(Person1 o1, Person1 o2) {
            //按照年龄排序
            return (int) (o1.getAge()-o2.getAge());
        }

    });
    System.out.println(Arrays.toString(array));

    Arrays.sort(array,new Comparator<Person1>() {

        @Override
        public int compare(Person1 o1, Person1 o2) {
            //按照成绩排序
            return (int) (o1.getScore()-o2.getScore());
        }

    });
    System.out.println(Arrays.toString(array));
}

可以看出来其运用了匿名内部类构建compare接口,在其内部实现排序的对比。
结果
[Person1 [name=three, age=3, score=1.0], Person1 [name=one, age=10, score=3.0], Person1 [name=two, age=26, score=2.0]]
[Person1 [name=three, age=3, score=1.0], Person1 [name=two, age=26, score=2.0], Person1 [name=one, age=10, score=3.0]]

猜你喜欢

转载自blog.csdn.net/qq_38345606/article/details/80436891