Java中抽象类与接口详解

文章介绍了Java中的抽象类和接口的概念及特性。抽象类用于表示类的抽象,不能实例化,可包含抽象方法和具体方法。接口则是完全抽象的,包含常量和抽象方法,支持多继承。面向接口编程能提高程序的扩展性和降低耦合度。一个类可以实现多个接口,但只能继承一个抽象类。
摘要由CSDN通过智能技术生成

        1.抽象类

1.1第一眼看抽象类

当我们第一眼见到这个抽象类名字的时候,我相信大家已经有了抽象类与普通类的一些感性认识,

抽象类顾名思义就是类的进一步抽象,我们第一次见到应该有了这样的认识.所谓抽象就是忽略事物的细节,关注事物的主体部分,同样的抽象与普通的类也有这样的关系. 那么让我们进一步的来了解抽象类吧.

1.2抽象的的概念

1.2.1 一个例子:

首先我们先举一个例子:当我们要实现一个程序来完成各种图形的绘制的时候,比如说正方形,矩形,圆形等等.按照我们之前没学过抽象类的时候,我们首先可以想到的是先定义一个图形的父类,并且这其中还有面积,周长等变量.然后再定义以个绘制图形的方法,.但是方法体好像写什么都不合适,方法中就是空语句,然后再去创建各个具体图形的子类并且去继承图形父类,并且重写父类中绘图的方法,然后使用多态机制,让父类型引用指向子类型对象,最后调用方法.这样当然是可行的.但是细想还是会有一些问题存在

        如果你不小心创建了父类的对象好像是什么用都没有,因为你没有具体的图形,里面的面积和周长,图形绘制都是没有必要的,进行相关操作是没有意义的,反而还会容易发生错误.

这时候就可以使用抽象类就再合适不过了

public class Test {
    public static void main(String[] args) {
        Graph squ=new Square();
        squ.Draw();
        Graph cir=new Circle();
        cir.Draw();
    }
}
// 图形类
abstract class Graph{
    public double s; // 面积
    public double c; // 周长
    public abstract double GetS(); // 计算面积
    public abstract double GetC(); // 计算周长
    public abstract void Draw(); //绘制图形
}
// 正方形类
class Square extends Graph{
    double a; // 边长

    @Override
    public double GetS() {
       return a*a;
    }

    @Override
    public double GetC() {
        return 4*a;
    }

    @Override
    public void Draw() {
        System.out.println("正方形");
    }
}
// 圆形类
class Circle extends Graph{
    double r; // 半径
    final static double PI=3.1415926;
    @Override
    public double GetS() {
       return PI*r*r;
    }

    @Override
    public double GetC() {
       return 2*PI*r;
    }

    @Override
    public void Draw() {
        System.out.println("圆形");
    }
}

以上代码是图形类的具体实现,看到这儿大家应该看到抽象类的作用了,和一些使用场景.

1.2.2 抽象类的概念

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

以上Graph就是抽象类,抽象类使用abstract修饰,但是抽象类是可以包含具体的行为和状态的

所以说抽象类是半抽象的,后面接口是完全抽象的.

1.3抽象类的特征

1.3.1

抽象类是不支持实例化的,也就是不能通过new关键字创建对象,抽象类就是被子类继承的.

抽象类中既可以有抽象方法,又可以有普通方法,和普通变量以及实例变量,所以前面才说抽象类并不是完全抽象的,抽象类是半抽象的.

抽象方法是没有方法体的方法,也就是没有实现的方法,抽象方法需要用abstract修饰

 1.3.2 与abstract 类的非法的修饰符组合

private

我们已经知道,抽象类就是为了被继承,但是private修饰的并不支持继承,自然抽象类中也不能有private修饰了

final

final修饰的类不支持继承,所以也不能与抽象类中abstract在一起使用

static

抽象方法不能用static修饰,static修饰的方法是类级别的方法,不是对象级别的方法.而抽象类使用来被继承的.

1.3.3 抽象类中需要注意的几点

1.抽象方法可以不出现在抽象类中,但是抽象方法一定是只能在抽象类中存在的(接口也是一种完全抽象的类)

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

1.3.4 抽象类的作用

抽象类的出现给了编译器多了一层编译时期的校验,以减少出错的概率,这样是很有意义的,就像前面

如果创建了普通类,就有可能出错,从而无法达到我们的需求和功能,这是很有必要的.

2.接口

2.1接口的概念:

提到接口我们日常生活中到处可见,比如所USB接口,充电器接口,电视机接口,集成电路上的各种接口.

接口:多个类的公共规范,是一种引用数据类型,接口是完全抽象的,接口中所有的变量都是常量,所有的方法都是抽象方法,但是在java8后接口中可以存在默认的有方法体的方法

 2.2接口的特征

2.2.1

定义接口使用interface关键字

 

接口中的方法都是抽象方法(默认方法除外),变量都是常量,并且访问权限都是public,所以我们在定义接口中的变量和抽象方法的时候public static final和public abstract可以省略不写,可以看到上面代码中对应的都变成灰色了.

2.2.2 接口支持多继承

 可以清楚的看到一个接口可以同时继承多个接口,这也叫做接口的合并,接口的多继承,和好的解决了

类的单继承的缺陷

2.2.3接口的使用

由于接口是完全抽象的,所以接口也是不能直接new 对象,那我们就自然想到了用一个普通类去继承一个接口,事实上也是很类似的,如果一个类想去使用一个接口,那么这个类就要去实现这个接口中所有的抽象方法,而类去继承接口,在这里有一个新的叫法:叫做类实现接口,并且使用关键字implements来代替之前继承的关键字extends.

并且一个类可以实现多个接口,也要重写这些接口中的抽象方法

同样的道理如果一个类没有实现接口中的抽象方法,那么这个类也一定是抽象类

到最后普通类继承这个抽象类的时候还是要重写这些抽象方法

 

当然如果不重写抽象方法的话,那D类也必须是抽象类

implements和extends同时存在

 

 要注意这两个关键字的使用顺序,先extends后implements

2.2.4面向接口编程

前面的抽象类可以面向抽象编程,就是抽象类引用指向之类的对象,也是充分利用多态机制

而这里的面向接口编程,则可以让我们忘记类型直接使用接口类型去引用被他实现的的类

这样就看不到类型了

public class Test {
    public static void main(String[] args) {
        Animal a=new Dog("小狗",8);
        test(a);
        test2(new Dog("二哈",5));
        test3(new Dog("1",1));
    }
    public static void test(Animal a){
        a.eat();
    }
    public static void test2(IRunning r){
        r.run();
    }
    public static void test3(ISwing s){
        s.swig();
    }
    public static void test4(IFlying f){
        f.fly();
    }
}
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();
}
 interface IFlying {
    void fly();
}
interface IRunning {
    void run();
}
interface ISwing {
    void swig();
}
class Dog extends Animal implements IFlying,ISwing,IRunning{
    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(name+"狗吃骨头");
    }

    @Override
    public void fly() {
        System.out.println(name+"狗飞快的跑");
    }

    @Override
    public void run() {
        System.out.println(name+"正在狗腿跑");
    }

    @Override
    public void swig() {
        System.out.println(name+"狗游泳");
    }
}

可以看到上面方法中的形参列表可有抽象类,接口.

在传参的时候如果该类继承或者实现了该接口,就会发生向上类型转换,这样整个程序的适配性就很会强了,只要是继承了该抽象类或是实现了这个接口都可以作为参数传递,大大提高了程序的扩展力,

降低了程序的耦合度.这就是面向接口编程和面向接口编程.

3.总结抽象类与接口

首先抽象类是半抽象的,接口是完全抽象的,这也决定了他们的不同

1.一个类可以实现(implements)多个接口,但是一个普通类只能继承(extends)一个抽象类

2.抽象类中可以存在普通方法和普通变量,而在接口中只存在常量和抽象方法

3.抽象类中可以有不同与public 的访问修饰符,而接口中的访问修饰符只能是public(默认方法除外)

4.抽象类可以实现若干接口,接口可以继承多个接口,但是接口不能继承抽象类

以上就是本次的全部内容,谢谢大家的观看

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qm_hu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值