轻松理解java中的抽象类与接口

目录

抽象类

接口

接口用static和default的方法

Comparable

Comparator

Comparable和Comrarator的区别

接口实现冒泡排序


抽象类

如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类

abstract class 类名{//抽象类

    abstract void shout();//抽象方法

}

1. 抽象类不能直接实例化对象

// 抽象类:被abstract修饰的类

public abstract class Shape {

// 抽象方法:被abstract修饰的方法,没有方法体

abstract public void draw();

abstract void calcArea();

// 抽象类也是类,也可以增加普通方法和属性

public double getArea(){

return area;

}

protected double area; // 面积

}

2. 抽象方法不能是 private

private 的 abstract class Shape {

abstract private void draw();

}

// 编译出错

Error:(4, 27) java: 非法的修饰符组合: abstract和private
3. 抽象方法不能被 final static 修饰,因为抽象方法要被子类重写
public abstract class Shape {

abstract final void methodA();

abstract public static void methodB();

}

4. 抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修 饰

// 矩形类

public class Rect extends Shape {

private double length;

private double width;

Rect(double length, double width){

this.length = length;

this.width = width;

}

public void draw(){

System.out.println("矩形: length= "+length+" width= " + width);

}

public void calcArea(){

area = length * width;

}

}

// 圆类:

public class Circle extends Shape{

private double r;

final private static double PI = 3.14;

public Circle(double r){

this.r = r;

}

public void draw(){

System.out.println("圆:r = "+r);

}

public void calcArea(){

area = PI * r * r;

}

}

// 三角形类:

public abstract class Triangle extends Shape {

private double a;

private double b;

private double c;

@Override

public void draw() {

System.out.println("三角形:a = "+a + " b = "+b+" c = "+c);

}

// 三角形:直角三角形、等腰三角形等,还可以继续细化

//@Override

//double calcArea(); // 编译失败:要么实现该抽象方法,要么将三角形设计为抽象类

}

5. 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类

6. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量

注意:抽象类也是类,内部可以包含普通方法和属性,甚至构造方法


接口

多个类的公共规范,可以说是属于一种标准,是一种引用数据类型

1. 接口类型是一种引用类型,但是不能直接new接口的对象

public class TestUSB {

public static void main(String[] args) {

USB usb = new USB();

}

}

// Error:(10, 19) java: day20210915.USB是抽象的; 无法实例化
2. 接口中每一个方法都是 public 的抽象方法 , 即接口中的方法会被隐式的指定为 public abstract (只能是 public abstract,其他修饰符都会报错 )

public interface USB {

// Error:(4, 18) java: 此处不允许使用修饰符private

private void openDevice();

void closeDevice();

}

3. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现

public interface USB {

void openDevice();

// 编译失败:因为接口中的方式默认为抽象方法

// Error:(5, 23) java: 接口抽象方法不能带有主体

void closeDevice(){

System.out.println("关闭USB设备");

}

}

4. 重写接口中方法时,不能使用默认的访问权限

public interface USB {

void openDevice(); // 默认是public的

void closeDevice(); // 默认是public的

}

public class Mouse implements USB {

@Override

void openDevice() {

System.out.println("打开鼠标");

}

// ...

}

// 编译报错,重写USB中openDevice方法时,不能使用默认修饰符

// 正在尝试分配更低的访问权限; 以前为public

5. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量

public interface USB {

double brand = 3.0; // 默认被:final public static修饰

void openDevice();

void closeDevice();

}

public class TestUSB {

public static void main(String[] args) {

System.out.println(USB.brand); // 可以直接通过接口名访问,说明是静态的

// 编译报错:Error:(12, 12) java: 无法为最终变量brand分配值

USB.brand = 2.0; // 说明brand具有final属性

}

}

6. 接口中不能有静态代码块和构造方法

public interface USB {

// 编译失败

public USB(){

}

{} // 编译失败

void openDevice();

void closeDevice();

}
7. 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是 .class
8. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
9. jdk8 中:接口中还可以包含 default 方法。


接口用static和default的方法

轻松理解java中的抽象类与接口_第1张图片

static不能重写第一个必须重写,第三个default可重写也可以不重写


Comparable

Comparable是接口,表示当前的类是可以进行比较的

class Student implements Comparable

<>括号里写的谁就比较谁

compareTo是Comparable这个接口的方法

Comparable的运用:如图

轻松理解java中的抽象类与接口_第2张图片

例子:

class Student implements Comparable {

    public String name;

    public int age;



    public Student(String name, int age) {

        this.name = name;

        this.age = age;

    }



    @Override

    public int compareTo(Student o) {

        return this.age - o.age;

        //return o.age - this.age;//从大到小

    }

/*        if (this.age > o.age) {

            return 1;

        } else if (this.age == o.age) {

            return 0;

        } else {

            return -1;

        }

    }*/



    @Override

    public String toString() {

        return "Student{" +

                "name='" + name + '\'' +

                ", age=" + age +

                '}';

    }

}



public class Test {

    public static void main(String[] args) {

        Student student1 = new Student("1", 10);

        Student student2 = new Student("11", 11);

        System.out.println(student1.compareTo(student2));

    }

}

轻松理解java中的抽象类与接口_第3张图片


Comparator

Comparator灵活一点,可以根据你想要的属性来排序,下面有例子可以看看

例子:

class 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 + '}';

    }

}



class AgeComparator implements Comparator {//AgeComparator如果想根据姓名比较,直接换成NameComparator



    @Override

    public int compare(Student o1, Student o2) {

        return o1.age - o2.age;

    }

}



class NameComparator implements Comparator {

    @Override

    public int compare(Student o1, Student o2) {



        //String 自己重写的 compareTo 方法

        return o1.name.compareTo(o2.name);

    }

}



public class Test {

    public static void main(String[] args) {

        Student student1 = new Student("1", 10);

        Student student2 = new Student("11", 11);



        AgeComparator ageComparator = new AgeComparator();

        System.out.println(ageComparator.compare(student1, student2));



        NameComparator nameComparator = new NameComparator();

        System.out.println(nameComparator.compare(student1, student2));



    }

}


Comparable和Comrarator的区别

Comrarator比较灵活,Comparable根据默认的属性来进行排序,不需要那么麻烦点

package demo1;



import java.util.Arrays;

import java.util.Comparator;



/**

 * Created with IntelliJ IDEA.

 * Description:

 * User: 楠

 * Date: 2024-02-03

 * Time: 15:17

 */



class Student implements Comparable {

    public String name;

    public int age;



    public Student(String name, int age) {

        this.name = name;

        this.age = age;

    }



    @Override

    public int compareTo(Student o) {

        return this.age - o.age;

    }



    @Override

    public String toString() {

        return "Student{" + "name='" + name + '\'' + ", age=" + age + '}';

    }

}



class AgeComparator implements Comparator {//AgeComparator如果想根据姓名比较,直接换成NameComparator



    @Override

    public int compare(Student o1, Student o2) {

        return o1.age - o2.age;//从大到小反过来

    }

}



class NameComparator implements Comparator {

    @Override

    public int compare(Student o1, Student o2) {



        //String 自己重写的 compareTo 方法

        return o1.name.compareTo(o2.name);

    }

}



public class Test {

    public static void main(String[] args) {

        Student[] students = new Student[3];

        students[0] = new Student("qwe", 18);

        students[1] = new Student("asd", 14);

        students[2] = new Student("zxc", 12);



        AgeComparator ageComparator = new AgeComparator();

        Arrays.sort(students);//这样就是默认的Comparable<>进行比较

        //Arrays.sort(students, ageComparator);//根据年龄排序,只能要改掉第二个参数以及源代码就可以按照你想要的格式排序

        System.out.println(Arrays.toString(students));



    }

}

注意事项: 对于 sort 方法来说, 需要传入的数组的每个对象都是 "可比较" 的, 需要具备 compareTo 这样的能力,通过重写 compareTo 方法的方式, 就可以定义比较规则


接口实现冒泡排序

前提是要实现接口comparable

为了进一步加深对接口的理解, 我们可以尝试自己实现一个 sort 方法来完成刚才的排序过程(使用冒泡排序)

轻松理解java中的抽象类与接口_第4张图片

你可能感兴趣的:(java,开发语言)