抽象类和接口

目录

抽象类

抽象类使用abstract修饰类

抽象类当中可以包含普通类所能包含的成员

抽象类和普通类不一样的是,抽象类当中可以包含抽象方法。

抽象类方法是使用abstract修饰的,这个方法没有具体的实现

不能实例化抽象类

抽象类存在的意义是为了被继承

抽象类的方法不能是私有的(private),要满足重写的规则。

抽象类当中可以有构造方法,为了方便子类能够调用,来初始化抽象类当中的成员

接口

1.使用interface来修饰接口

2.接口当中的成员方法不能有具体的实现。

 在接口中抽象方法默认是public abstract的方法

接口不可以被实例化,也就是说接口不能有静态代码块和构造方法

可以通过implements实现接口,接口里面的抽象方法必须重写,默认方法可重写也可以不重写,静态方法不能被重写。

接口的使用

实现多个接口

 抽象类和接口的区别:

Object类

toString

equals


抽象类

抽象类使用abstract修饰类

抽象类当中可以包含普通类所能包含的成员

抽象类和普通类不一样的是,抽象类当中可以包含抽象方法。

抽象类方法是使用abstract修饰的,这个方法没有具体的实现

abstract class Shape{
    public int a;
    public abstract void draw();
    public void func(){

    }
}

不能实例化抽象类

public class Test {
    public static void main(String[] args) {
        Shape shape = new Shape();//报错
    }
}

抽象类存在的意义是为了被继承

如果一个普通类继承了抽象类,此时必须重写抽象类中的方法。

class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("矩形");
    }
}

一个抽象类A继承一个抽象类B,此时不需要重写B中的抽象方法,但当A被继承时,还是要重写B中的抽象方法。

抽象类的方法不能是私有的(private),要满足重写的规则。

抽象类当中可以有构造方法,为了方便子类能够调用,来初始化抽象类当中的成员

接口

Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。

1.使用interface来修饰接口

2.接口当中的成员方法不能有具体的实现。

interface IShape {
    public abstract void func1();
    public void func2(){
        //报错
    }
}

 在接口中抽象方法默认是public abstract的方法

从JDK1.8开始,允许有方法的实现,但是这个方法必须是有default修饰的

可以实现有静态方法

成员变量默认是public static final修饰的,子类如果重写抽象方法必须由public修饰

interface IShape {
    public static final int a = 10;
    int b = 20;//默认也是public static final修饰的
    public abstract void func1();
    void func();//默认也是public abstract修饰的
    public void func2(){
        //报错
    }
    default public void func3(){
        System.out.println("默认方法");
    }
    public static void func4(){
        System.out.println("static修饰的方法");
    }
}

接口不可以被实例化,也就是说接口不能有静态代码块和构造方法

 public static void main(String[] args) {
        IShape ishape = new IShape();//报错
    }

可以通过implements实现接口,接口里面的抽象方法必须重写,默认方法可重写也可以不重写,静态方法不能被重写。

class A implements IShape{
    public void func1(){
        System.out.println("重写抽象方法");
    }
}

接口的使用

请实现笔记本电脑使用 USB 鼠标、 USB 键盘的例子
1. USB 接口:包含打开设备、关闭设备功能
//USB接口
public interface USB {
    void openDevice();
    void closeDevice();
}
2. 鼠标类:实现 USB 接口,并具备点击功能
public class Mouse implements USB{
    @Override
    public void openDevice() {
        System.out.println("打开鼠标");
    }
    @Override
    public void closeDevice(){
        System.out.println("关闭鼠标");
    }
    public void click(){
        System.out.println("鼠标点击");
    }
}

3. 键盘类:实现USB接口,并具备输入功能

public class KeyBoard implements USB {
    @Override
    public void openDevice() {
        System.out.println("打开键盘");
    }
    @Override
    public void closeDevice() {
        System.out.println("关闭键盘");
    }
    public void inPut(){
        System.out.println("键盘输入");
    }
}

4. 笔记本类:包含开机功能、关机功能、使用 USB 设备功能
public class Computer{
    public void powerOn(){
        System.out.println("打开笔记本电脑");
    }
    public void powerOff(){
        System.out.println("关闭笔记本电脑");
    }
    public void useDevice(USB usb){
        usb.openDevice();
        if(usb instanceof Mouse){
            Mouse mouse = (Mouse) usb;
            mouse.click();
        }
        if(usb instanceof KeyBoard){
            KeyBoard keyboard = (KeyBoard) usb;
            keyboard.inPut();
        }
        usb.closeDevice();
    }
}

测试:

//测试
public class TestUsb {
    public static void main(String[] args){
        Computer computer = new Computer();
        computer.powerOn();
        computer.useDevice(new Mouse());
        computer.useDevice(new KeyBoard());
        computer.powerOff();
    }
}

抽象类和接口_第1张图片

实现多个接口

一个类可以实现多个接口,使用implements 用逗号隔开。(可以解决多继承的问题)
interface  A{
    void func1();
}
interface B{
    void func2();
}
class C implements A,B{
    @Override
    public void func1() {
        System.out.println(1);
    }

    @Override
    public void func2() {
        System.out.println(2);
    }
}

接口实现多继承和多态简单实例

class Animal{
    public String name;
    public int age;
    public Animal(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void eat(){
        System.out.println("吃饭");
    }
}
interface IRuning{
    void runing();
}
interface ISwimming{
    void swimming();
}
interface IFly{
    void fly();
}
class Dog extends Animal implements IRuning,ISwimming{
    public Dog(String name,int age){
        super(name,age);
    }
    @Override
    public void runing() {
        System.out.println(name+"正在跑");
    }

    @Override
    public void swimming() {
        System.out.println(name+"正在游泳");
    }
}
class Duck extends Animal implements IRuning,ISwimming,IFly{
    public Duck(String name,int age){
        super(name,age);
    }
    @Override
    public void runing() {
        System.out.println(name+"正在跑");
    }

    @Override
    public void swimming() {
        System.out.println(name+"正在游泳");
    }

    @Override
    public void fly() {
        System.out.println(name+"正在飞");
    }
}
public class Test {
    public static void walk(IRuning iruning){
        iruning.runing();//多态
    }

    public static void main(String[] args) {
        walk(new Dog("小黑",2));
        walk(new Duck("可达鸭",3));
    }
}

抽象类和接口_第2张图片

 继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性

有了接口之后 , 类的使用者就不必关注具体类型 , 而只关注某个类是否具备某种能力
class Robot implements IRuning{

    @Override
    public void runing() {
        System.out.println("机器人正在跑步");
    }
}
public class Test {
    public static void walk(IRuning iruning){
        iruning.runing();
    }

    public static void main(String[] args) {
        walk(new Dog("小黑",2));
        walk(new Duck("可达鸭",3));
        walk(new Robot());
    }
}

抽象类和接口_第3张图片

机器人不是动物,但仍然可以实现多态,因为接口只关注某个类是否具有某种能力。机器人有跑步的能力,那他就可以实现。

 抽象类和接口的区别:

抽象类可以包含普通字段和成员,接口中不能包含普通方法,子类必须重写所有的抽象方法

抽象方法由普通类(普通字段和方法)和抽象方法组成

接口由抽象方法和全局常量组成

使用extends继承抽象类,使用implements关键字实现接口

一个抽象类可以实现若干个接口,接口不能继承抽象类,接口可以使用extends继承多个父类接口

一个子类只能继承一个抽象类,一个子类可以实现多个接口

Object类

Object类是所以类的父类,我们自己写的类就算没有写extends Object,默认也是继承的

class Teacher{

}
class Student{

}
public class Test2 {
    public static void func(Object object){
        
    }

    public static void main(String[] args) {
        func(new Student());//向上转型,不报错
        func(new Teacher());
    }
}

Object类当中的一些方法:

抽象类和接口_第4张图片

toString

输出对象的名称,和@符号后面跟一串16进制数字,该数字是由hashCode这个方法产生的 

equals

Java 中, == 进行比较时:
如果==左右两侧是基本类型变量,比较的是变量中值是否相同
如果==左右两侧是引用类型变量,比较的是引用变量地址是否相同
如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的
Object类中的equals方法

抽象类和接口_第5张图片

 可见Object类中的equals是使用引用中的地址来进行比较的

class Person{
    String name;
    int age;
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
}
public class Test3 {
    public static void main(String[] args) {
        Person per1 = new Person("zhangsan",20);
        Person per2 = new Person("zhangsan",20);
        int a = 10;
        int b = 10;
        System.out.println(a==b);
        System.out.println(per1==per2);
        System.out.println(per1.equals(per2));
    }
}

抽象类和接口_第6张图片

Person类重写equals方法:

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

    @Override
    public boolean equals(Object obj) {
        if(obj==null){
            return false;
        }
        if(this == obj){
            return true;
        }
        if(!(obj instanceof Person)){
            return false;
        }
        Person per = (Person) obj;
        if(this.name.equals(per.name) && this.age == per.age){
            return true;
        }else{
            return false;
        }
    }
}
public class Test3 {
    public static void main(String[] args) {
        Person per1 = new Person("zhangsan",20);
        Person per2 = new Person("zhangsan",20);
        int a = 10;
        int b = 10;
        System.out.println(a==b);
        System.out.println(per1==per2);
        System.out.println(per1.equals(per2));
    }
}

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