抽象类与接口


前言

这篇文章主要记录对抽象类和接口的理解。


一、抽象类是什么?

1.使用abstract修饰的方法叫做抽象方法,包含抽象方法的类叫做抽象类;
2.继承抽象类的类需要重写抽象类中的所有抽象方法,否则编译器会报错;
3.抽象类继承抽象类可以暂时不重写抽象方法;
4.抽象类的访问权限不能用private并且不能使用static、final修饰。

1.示例

代码如下(示例):

//抽象类
abstract class USB {
    public abstract void use();
}
class Mouse extends USB {
	//继承抽象类的类需要重写抽象类中的所有抽象方法
    @Override
    public void use() {
        System.out.println("Mouse");
    }
}

二、接口(interface)

1、接口中的成员变量默认都是public static final修饰;
2、接口中的方法默认是抽象方法,用public abstract修饰;
3、接口中的普通成员方法是不能有具体实现的除非加default;
4、接口不能被实例化,接口中不能有静态、实例代码块、构造方法;
5、类和接口的关联是通过implement进行实现的。

1.实例

代码如下(示例):

//接口
interface Shape {
    public static final int count = 3;//接口中的成员变量默认是public static final修饰
    void draw();//接口中的方法默认是抽象方法,使用public abstract修饰
}
//类与接口用implement实现关联
class Rect implements Shape {
    //实现接口的类需要重写接口中的所有抽象方法
    @Override
    public void draw() {
        System.out.println("□");
    }
}
class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("○");
    }
}
class Flower implements Shape {
    @Override
    public void draw() {
        System.out.println("❀");
    }
}
public class TestDemo2 {
    public static void drawShape(Shape shape){
        shape.draw();
    }

    public static void main(String[] args) {
        drawShape(new Rect());
        drawShape(new Circle());
        drawShape(new Flower());
    }
}

2.实现多个接口

一个类先继承后实现,只能继承一个类可以实现多个接口。
代码如下(示例):

class Animal {
    String name;//成员变量
    int age;
    //构造方法
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
//接口
interface IEating {
    void eat();
}
interface IFlying {
    void fly();
}
interface IRunning {
    void run();
}
interface ISwimming {
    void swim();
}
//一个类只能继承一个类,但是可以实现多个接口
class Dog extends Animal implements IEating,IRunning,ISwimming {

    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(name+" "+age+"岁,正在吃~");
    }

    @Override
    public void run() {
        System.out.println(name+" "+age+"岁,正在跑~");
    }

    @Override
    public void swim() {
        System.out.println(name+" "+age+"岁,正在游泳~");
    }
}
class Bird extends Animal implements IEating,IFlying,IRunning {

    public Bird(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(name+" "+age+"岁,正在吃~");
    }

    @Override
    public void fly() {
        System.out.println(name+" "+age+"岁,正在飞~");
    }

    @Override
    public void run() {
        System.out.println(name+" "+age+"岁,正在跑~");
    }
}
public class TestDemo3 {
    public static void eat(IEating iEating) {
        iEating.eat();
    }
    public static void fly(IFlying iFlying) {
        iFlying.fly();
    }
    public static void run(IRunning iRunning) {
        iRunning.run();
    }
    public static void swim(ISwimming iSwimming) {
        iSwimming.swim();
    }
    public static void main(String[] args) {
        eat(new Dog("小白",1));
        run(new Dog("小白",1));
        swim(new Dog("小白",1));
        System.out.println("===================");
        eat(new Bird("小鸟",2));
        fly(new Bird("小鸟",2));
        run(new Bird("小鸟",2));

    }
}


三、自定义类型如何比较大小?

基本数据类型可以直接比较他们的大小,可是自定义的类型,例如:学生,如何去对学生这个类进行大小比较,如下介绍两种方法:

1.Comparable

代码如下(示例):

//Comparable接口
class Student implements Comparable<Student> {
    String name;
    int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    //重写compareTo方法
    @Override
    public int compareTo(Student o) {
        return this.age-o.age;
    }
}
public class TestDemo4 {
    public static void main(String[] args) {
        Student[] arr = {new Student("李三",20),new Student("张思",19)};
        System.out.println("排序前"+Arrays.toString(arr));
        Arrays.sort(arr);
        System.out.println("排序后"+Arrays.toString(arr));
    }
}

2.Comparator

代码如下(示例):

//第二种方法:比较器 Comparator接口
class Student {
    String name;
    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<Student> {

    @Override
    public int compare(Student o1, Student o2) {
        return o1.age - o2.age;
    }
}
class NameComparator implements Comparator<Student> {

    @Override
    public int compare(Student o1, Student o2) {
        return o2.name.compareTo(o1.name);
    }
}
public class TestDemo4 {
	//模拟的sort排序
    public static void sort(Comparable[] array) {
        for (int i = 0; i < array.length-1; i++) {
            for (int j = 0; j < array.length-i-1; j++) {
                if(array[j].compareTo(array[j+1])>0) {
                    Comparable tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                }
            }
        }
    }
    public static void main(String[] args) {
        Student[] students = {new Student("李三",20),new Student("张思",19),new Student("阿伟",23)};
        System.out.println("排序前"+Arrays.toString(students));
        Arrays.sort(students,new AgeComparator());
        System.out.println("排序后"+Arrays.toString(students));
        Arrays.sort(students,new NameComparator());
        System.out.println("排序后"+Arrays.toString(students));
    }

四、Clone实现深拷贝与浅拷贝

1.浅拷贝

改变一个会影响另一个
代码如下(示例):

//浅拷贝:改变一个会影响另一个
class Money {
    public double money = 11.1;
}
class Person implements Cloneable{
    public int age;
    public Money money = new Money();

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class TestDemo5 {
    public static void main(String[] args) throws CloneNotSupportedException{
        Person person = new Person();
        Person person1 = (Person) person.clone();//浅拷贝
        System.out.println("person:"+person.money.money);
        System.out.println("person:"+person1.money.money);
        person.money.money = 12.12;
        System.out.println("person:"+person.money.money);
        System.out.println("person:"+person1.money.money);
    }
 }

在这里插入图片描述

2.深拷贝

改变一个不会影响另一个
代码如下(示例):

class Money implements Cloneable{
    public double money = 11.1;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public int age;
    public Money money = new Money();

    //实现深拷贝
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();
        tmp.money = (Money) this.money.clone();
        return tmp;
    }
}

在这里插入图片描述

五、抽象类、接口的区别和联系

1.区别:
(1)抽象类中有普通类和抽象方法,接口中只有抽象方法和public static final修饰的全局常量;
(2)抽象类与类之间使用extends关键字继承,接口与类之间使用implements关键字实现;
(3)一个类只能继承一个抽象类,但是一个类可以实现多个接口;
(4)一个抽象类可以实现若干接口,但是接口不能继承抽象类,只能继承多个父类接口。
2.联系:
抽象类和接口都不可以实例化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值