Java抽象类和接口详解

本文详细介绍了Java中的抽象类和接口,包括抽象类的定义、抽象方法的使用、抽象类的特性(如不能直接实例化和抽象方法要求重写),以及接口的概念(如publicabstract方法和接口间的多继承)。通过实例代码展示了如何在实际编程中运用这些概念。
摘要由CSDN通过智能技术生成

1.抽象类的概念和语法实现

  当一个类中的信息不足以描述一个具体的对象的时候,我们可以将这个类定义为抽象类。那么我们怎么定义出一个抽象类呢?我们要采用一个关键字abstract。下面我们来看具体代码:

abstract class Animal {
    public String name;
    public int age;

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

    public abstract void eat();//该方法被abstract修饰,是一个抽象方法不需要具体的实现,也就是不用写大括号及里面的实现


}//该类就是一个抽象类
class Dog extends Animal{
    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(this.name + "正在吃狗粮");
    }
}
class Cat extends Animal{
    public Cat(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(this.name + "正在吃猫粮");

    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal1 = new Dog("小黄",10);
        Animal animal2 = new Cat("小花",5);
        animal1.eat();
        animal2.eat();
    }

}

 

这里代码中的Animal便是一个抽象类,被关键字abstract修饰。我们通过主函数的调用便发生了向上转型,动态绑定,发生了多态。所以抽象类也是可以发生多态的。我们可以看到抽象类当中也有普通成员变量和普通的方法。所以我们可以总结

1)抽象类要使用abstract关键字进行修饰。(2)抽象类和普通类一样可以定义成员变量和成员方法,构造方法等,也可以实现多态。当然还要注意一点抽象类和普通类的一个区别:抽象类不可以直接实例化对象。

仔细观察代码我们也可以看到eat()方法,没有具体的实现(就是没有大括号以及括号里面的语句),这就是抽象方法的语法格式。抽象方法必须要被abstract修饰,当子类继承是,必须重写我们父类的抽象方法。

可以看到当子类没有重写父类的抽象方法是,编译报错了。 当一个类中有抽象方法时这个类必需修被修饰成抽象类。那么我们什么时候用抽象方法呢?当这个方法本身没有具体修饰的对象,就是用来被继承的子类使用的时候,我们可以将这个方法修饰为抽象方法。

2.抽象类的特性和作用

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

 (2)抽象方法不能被private修饰

(3)抽象方法不能被static和final修饰(因为子类要重写该抽象方法)

 

(4) 抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用abstract修饰。(但是如果子类再被继承就要重写全部的抽象方法

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

 

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

3.接口的概念及语法实现

接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。 在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。下面我们来实现一个有接口的代码再刨析它:

先定义一个接口:

下面写代码来调用这个接口:

class Circle implements IGraph{
    @Override
    public void fun() {
        System.out.println("画一个圆圈");
    }
}
class Triangle implements IGraph {

    @Override
    public void fun() {
        System.out.println("画一个三角形");
    }
}
class Flower implements IGraph{
    @Override
    public void fun() {
        System.out.println("画一朵花");
    }
}
public class GraphOut {
    public static void main(String[] args) {
        Circle circle = new Circle();
        circle.fun();
        Triangle triangle = new Triangle();
        triangle.fun();
        Flower flower = new Flower();
        flower.fun();
    }
}

 

这里我们便实现了接口的调用。我们现在来了解一下接口这个知识:定义接口要使用一个关键字interface,创建接口时, 接口的命名一般以大写字母 I 开头。接口中的方法默认为public abstract修饰的抽象方法,当然接口中也可以有“变量”,“变量”默认被public static final修饰,因此这里的变量实际上被修饰成了一个静态的常量,故必修初始化相应的值,且不允许被修改。接口中也可以存在能具体实现的方法,如被default和static修饰的方法。接口的使用就要使用关键字implements来实现接口。

 最后接口需要注意一点:一个类实现了接口就说明这个类具备了这个接口的功能,不一定要通过接口中的方法重写来实现接口的功能。(这个将在后面讲clone接口时会体现到)

4.接口的特性

(1)接口类型是一种引用类型,但是不能直接new接口的对象(这里和抽象类一样不能直接实例化对象)

(2)接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)

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

 

(4)重写接口中方法时,不能使用默认的访问权限(其实也就是重写接口方法时,使用的权限不能比接口的访问权限小,可以大于等于接口中方法的权限) 

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

(6)接口中不能有静态代码块,实例代码块和构造方法

(7) 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类

5.实现多个接口和接口间的继承

实现多个接口其实就是让这个类具备多个功能。下面我们来实现一下:

interface Running {
    void run();
}

interface Swiming {
    void swim();
}

interface Fly {
    void fly();
}

class Duck implements Running,Swiming,Fly {
    @Override
    public void run() {
        System.out.println("鸭子在跑");
    }

    @Override
    public void swim() {
        System.out.println("鸭子在游泳");
    }

    @Override
    public void fly() {
        System.out.println("鸭子在飞");
    }
}
public class TestInter {
    public static void main(String[] args) {
        Duck duck = new Duck();
        duck.run();
        duck.swim();
        duck.fly();
    }
}

 

从上面的代码中我们可以看到Duck这个类实现了多个接口,在实现多个接口后要重写接口中的所有抽象方法。这里我们就说Duck这个类具备了Running,Swimming,Fly这三个功能。 

注意:一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类。

下面我们来看看接口间的多继承问题,接口区别于普通的类,接口不仅可以实现单继承,还可以实现多继承。下面我们演示一下接口间多继承的实现:

interface Running {
    void run();
}

interface Swimming {
    void swim();
}

interface Fly {
    void fly();
}
interface Behavior extends Running,Swimming,Fly{
    void behavior();
}

class Duck implements Behavior {
    @Override
    public void behavior() {
        System.out.println("鸭子有多种行为");
    }

    @Override
    public void run() {
        System.out.println("鸭子在跑");
    }

    @Override
    public void swim() {
        System.out.println("鸭子在游泳");
    }

    @Override
    public void fly() {
        System.out.println("鸭子在飞");
    }
}

接口间的多继承其实就是将各个接口的功能集合到一个接口中,当然该子类接口也可以有自己的功能。当你完成了多继承后,你再实现这个接口就要重写所有接口的抽象方法。 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值