Java之抽象类和接口以及两者区别

本文详细介绍了Java中的抽象类和接口的概念、特点及使用方法。包括抽象类的定义、抽象方法、构造函数和成员测试等内容,同时对比了抽象类与接口的区别。

抽象类

概念

  • Java中可以定义被abstract关键字修饰的方法,这种方法只有声明,没有方法体,叫做抽象方法.
  • Java中可以定义被abstract关键字修饰的类,被abstract关键字修饰的类叫做抽象类
  1. 如果一个类含有抽象方法,那么它一定是抽象类
  2. 如果一个类是抽象类,那么它可以不含有抽象方法
  3. 抽象类中的方法实现交给子类来完成(不写方法体是为了满足各个子类对该方法执行不同的行为)

抽象方法的格式:

权限修饰符  abstract  返回值类型  方法名(参数列表);

特别注意:抽象方法没有方法体

特点

  • abstract 可以修饰方法或者类
  • 被abstarct修饰的类叫做抽象类,被abstract修饰的方法叫做抽象方法
  • 抽象类中可以没有抽象方法
  • 如果类中有抽象方法,那么该类必须定义为一个抽象类
  • 子类继承了抽象类以后,要么还是一个抽象类,要么就把父类的所有抽象方法都重写
  • 多用于多态中
  • 抽象类不可以被实例化(不能创建对象),可以使用多态

注意:

当一个子类继承了抽象父类以后,有两种解决方案:
1.变成抽象子类,"躺平,我也不实现,继续抽象"
2.重写父类中所有的抽象方法,"父债子偿",注意是所有
package cn.tedu.test1;
public class AbstractDemo {
    public static void main(String[] args) {
//        Animal a = new Animal();  //抽象类不能实例化(不能创建对象)
        Pig pig = new Pig();        //在这里Pig类不是抽象类
        Animal animal = new Pig();  //可以使用多态
        animal.fly();
        animal.fly2();
    }
}
abstract class Animal{    //定义一个抽象类

    public void eat(){                //抽象类可以定义普通方法
        System.out.println("吃啥都行~");
    }
    public void play(){
        System.out.println("玩啥都行~");
    }
    public abstract void fly();     //定义抽象方法,注意抽象方法没有方法体
    public abstract void fly2();    //定义抽象方法
}
//当一个子类继承了抽象父类以后,有两种解决方案:
//1.变成抽象子类,"躺平,我也不实现,继续抽象"
//2.重写父类中所有的抽象方法,"父债子偿"
class Pig extends Animal{
    @Override
    public void fly(){  //重写父类所有抽象方法
        System.out.println("猪也能飞");
    }
    @Override
    public void fly2(){ //重写父类所有抽象方法
        System.out.println("母猪也能上树");
    }
}
//abstract class Pig extends Animal{}//变成抽象子类

结果显示:
猪也能飞
母猪也能上树

抽象类构造函数测试

1.抽象类中可以有构造方法
2.父类的构造方法要优先于子类执行
3.抽象类不可以创建对象(实例化)
4.抽象类中存在的构造方法不是为了创建本类对象时调用
  而是为了创建子类对象时使用(一切为了孩子)
package cn.tedu.test1;
/*
 * 1.抽象类中可以有构造方法
 * 2.父类的构造方法要优先于子类执行
 * 3.抽象类不可以创建对象(实例化)
 * 4.抽象类中存在的构造方法不是为了创建本类对象时调用
 * 而是为了创建子类对象时使用
 * */
public class AbstractDemo2 {
    public static void main(String[] args) {
        //    Animal2 a = new Animal2();//抽象类不可以实例化
        Pig2 pig2 = new Pig2();//抽象类中的构造函数通常在子类对象实例化时使用
        pig2.eat();
    }
}
abstract class Animal2{
    public Animal2(){   //抽象父类创建构造方法不是为了自己使用,而是为了子类创建对象时使用
        System.out.println("我是Animal2的构造方法");
    }
    public abstract void eat();
}
class Pig2 extends Animal2{
    public Pig2(){
//        super();//默认存在父类的构造方法
        System.out.println("我是Pig2的构造方法");
    }
    public void eat(){
        System.out.println("猪猪吃猪料");
    }
}
结果显示:
我是Animal2的构造方法
我是Pig2的构造方法
猪猪吃猪料

抽象类成员测试

抽象类中可以定义普通方法且可以都是普通方法
问题:如果一个类里面都是普通方法,那为什么还要被修饰成抽象类?
答:因为抽象类不可以被实例化,所以如果不想让外界创建本类的对象,就可以把普通类声明成抽象类
package cn.tedu.test1;
public class AbstractDemo3 {
    public static void main(String[] args) {
        Fruit fruit = new Banana();
        System.out.println(fruit.name);
        fruit.eat();
        fruit.clean();
    }
}
abstract class Fruit{
    //抽象类中可以定义成员变量
    int sum = 100;
    //抽象类中可以定义成员常量
    final String name = "zll";  //注意final修饰的常量要初始化
    //抽象类中可以定义普通方法且可以都是普通方法
    //如果一个类里面都是普通方法,那为什么还要被修饰成抽象类?
    //因为抽象类不可以被实例化,所以如果不想让外界创建本类的对象,就可以把普通类声明成抽象类
    public void eat(){
        System.out.println("水果好吃");
    }
    public abstract void clean();
}
class Banana extends Fruit{
    @Override
    public void clean(){
        System.out.println("香蕉不用洗");
    }
}
结果显示:
zll
水果好吃
香蕉不用洗

抽象类综合使用案例

package cn.tedu.design;
/*设计老师类,要求:面向抽象编程--后天向上抽取形成的结果(先把各类老师需要的属性、方法都老实写出来,然后才发现这些共同的属性和方法,才向上抽取这些共性,形成规则)*/
public class DesignTeacher1 {
    public static void main(String[] args) {
        CGBTeacher ct = new CGBTeacher();
        ct.ready();
        ct.teach();
        ACTTeacher at = new ACTTeacher();
        at.ready();
        at.teach();
        SCDTeacher st = new SCDTeacher();
        st.ready();
        st.teach();
    }
}
abstract class Teacher{  //创建老师类,为各类老师的父类,提取所有老师的共性,减少代码的冗余
    String name;//姓名
    int id;//工号
//    public void teach(){    //改变各类老师的讲课内容,就需要用到抽象方法
//        System.out.println("正在讲课");
//    }
        public abstract void teach();
//    public void ready(){    //改变各类老师的备课内容
//        System.out.println("正在备课");
//    }
        public abstract void ready();
}
//1.创建培优老师类
class CGBTeacher extends Teacher{

    @Override
    public void teach() {
        System.out.println("CGB正在讲课...CGB");
    }

    @Override
    public void ready() {
        System.out.println("CGB正在备课...CGB");

    }
}
class ACTTeacher extends Teacher{

    @Override
    public void teach() {
        System.out.println("ACT正在讲课...ACT");
    }

    @Override
    public void ready() {
        System.out.println("ACT正在备课...ACT");
    }
}
class SCDTeacher extends Teacher{

    @Override
    public void teach() {
        System.out.println("SCD正在讲课...SCD");
    }

    @Override
    public void ready() {
        System.out.println("SCD正在备课...SCD");
    }
}

 结果显示:

CGB正在备课...CGB
CGB正在讲课...CGB
ACT正在备课...ACT
ACT正在讲课...ACT
SCD正在备课...SCD
SCD正在讲课...SCD

接口

概念

与抽象类一样,接口( Interface )在Java中也是一种抽象类型,接口中的内容是抽象形成的需要实现的功能,接口更像是一种规则和一套标准.

接口可以看作是一个特殊的抽象类,因为它里面全是抽象方法。

接口格式

修饰符 interface 接口名{  代码...  }

特点

  1. 通过interface关键字来定义接口
  2. 通过implements让子类来实现接口
  3. 接口中的方法全部都是抽象方法(JAVA8)
  4. 可以把接口理解成一个特殊的抽象类(但接口不是类!!!)
  5. 类描述的是一类事物的属性和方法,接口则是包含实现类要实现的方法
  6. 接口突破了java单继承的局限性
  7. 接口和类之间可以多实现,接口与接口之间可以多继承
  8. 接口是对外暴露的规则,是一套开发规范
  9. 接口提高了程序的功能拓展,降低了耦合性
     

接口使用

1.创建接口

package cn.tedu.inter;
/*本接口用于接口创建测试
通过interface关键字来定义接口
 */
public interface Inter {
    /*接口中不可以定义普通方法*/
//    public void eat(){}
    /*接口中的方法都是抽象方法*/
    public abstract void eat();
    public abstract void play();
}

2.创建接口实现类

package cn.tedu.inter;
/*本类作为Inter接口的实现类*/
    /*1.实现类如果想要和接口建立实现关系,通过implements来实现*/
    /*2.接口实现类与接口建立关系之后,有两种解决方案:
    * 方案一:作为抽象子类,不实现任何抽象方法
    * 方案二:作为普通子类,实现父级接口中所有的抽象方法*/
//abstract public class InterImpl implements Inter{}//方法一:直接抽象
public class InterImpl implements Inter{

    @Override               //方法二:实现父接口的抽象方法
    public void eat() {
        System.out.println("吃粽子");
    }

    @Override               //实现父接口的抽象方法
    public void play() {
        System.out.println("划龙舟");
    }
}

3.创建接口测试类

package cn.tedu.inter;
/*本类用于测试接口的实现类*/
public class InterTests {
    //创建程序的入口函数
    public static void main(String[] args) {
//        Inter i = new Inter();//接口不可以创建对象
        Inter inter = new InterImpl();//创建多态对象测试
        inter.eat();
        inter.play();
        InterImpl inter1 = new InterImpl();//创建子类对象进行测试
        inter1.eat();
        inter1.play();
    }
}

接口之构造方法

package cn.tedu.inter2;
/*本类用于进一步测试接口的使用*/
public class TestUserInter {
    public static void main(String[] args) {
        Inter2 inter2 = new Inter2Impl();//
        inter2.eat();
    }
}
/*1.创建接口*/
interface Inter2{       //接口中都是抽象方法
//    public Inter2(){} //接口中没有构造方法
    public abstract void eat();//创建接口的抽象方法
    void eat2();     //接口中的方法简写,默认是抽象方法,会自动拼接
}
/*如果一个类没有明确指定父类,那么它的父类就是Object顶级父类*/
//class Inter2Impl extends Object implements Inter2{
/*2.创建接口实现类*/
class Inter2Impl implements Inter2{
    //3.创建子类的构造方法
    public Inter2Impl(){
        super();//默认调用Object的无参构造
        System.out.println("我是实现类Inter2Impl的构造方法~");
    }
    @Override
    public void eat(){  //实现父级接口的eat()方法
        System.out.println("端午干粽子");
    }
}

结果显示:

我是实现类Inter2Impl的构造方法~
端午干粽子

总结:接口里是没有构造方法的,接口中的方法全是抽象方法,而且可以简写方法,void eat2()

在创建实现类的对象时默认的super(),是调用的默认Object的无参构造

接口之成员变量

注意:接口中没有普通成员变量,有的只是静态常量,当定义int i = 10时;会默认拼接成public static final int i = 10;

package cn.tedu.inter2;
/*本类用于进一步测试接口的使用*/
public class TestUserInter {
    public static void main(String[] args) {
        Inter2 inter2 = new Inter2Impl();
        inter2.eat();
        System.out.println(Inter2Impl.age);
        System.out.println(inter2.age);
    }
}
/*1.创建接口*/
interface Inter2{
//    public Inter2(){} //接口中没有构造方法
    public abstract void eat();//创建接口的抽象方法
    /*接口中没有成员变量*/
    int age = 22;   //必须初始化赋值,是静态常量,实际写法:public static final int age = 22;在接口中可以省略不写,接口里都是静态常量
}
/*如果一个类没有明确指定父类,那么它的父类就是Object顶级父类*/
//class Inter2Impl extends Object implements Inter2{
/*2.创建接口实现类*/
class Inter2Impl implements Inter2{
    //3.创建子类的构造方法
    public Inter2Impl(){
        super();
        System.out.println("我是实现类Inter2Impl的构造方法~");
    }
    @Override
    public void eat(){  //重写父级eat()方法
        System.out.println("端午干粽子");
    }
}

结果显示:

我是实现类Inter2Impl的构造方法~
端午干粽子
22
22

接口之综合案例

package cn.tedu.design;
/*设计老师类,要求:面向接口编程--先天设计的结果(直接预先设计出规则)*/
public class DesignTeacher2 {
    public static void main(String[] args) {
        Teacher2 act = new ACTTeacher2();
        act.ready();
        act.teach();
        Teacher2 cgb = new CGBTeacher2();
        cgb.ready();
        cgb.teach();
//        Teacher2 scd = new SCDTeacher2();//抽象类不能被实例化(不能创建对象)
    }
}
//1.创建接口,设计形成父级接口--接口体现的是预先定义好的规则
interface Teacher2{//接口里的方法默认都是抽象方法,所以可以简写
    void ready();
    void teach();
}
//2.创建接口实现类
class ACTTeacher2 implements Teacher2{

    @Override
    public void ready() {
        System.out.println("ACT老师在备课");
    }

    @Override
    public void teach() {
        System.out.println("ACT老师在上课");
    }
}
class CGBTeacher2 implements Teacher2{

    @Override
    public void ready() {
        System.out.println("CGB老师在备课");
    }

    @Override
    public void teach() {
        System.out.println("CGB老师在上课");
    }
}
abstract class SCDTeacher2 implements Teacher2{//抽象类
    @Override
    public void ready(){
        System.out.println("SCD老师在备课");
    }
    public abstract void teach();//抽象方法
}

结果显示:

ACT老师在备课
ACT老师在上课
CGB老师在备课
CGB老师在上课

抽象类与接口区别

面向抽象编程--后天向上抽取形成的结果(先把各类老师需要的属性、方法都老实写出来,然后才发现这些共同的属性和方法,才向上抽取这些共性,形成规则)。

面向接口编程--先天设计的结果(直接预先设计出规则)。

主要区别:

1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4.抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5.抽象类中可以包含静态方法,接口中不能包含静态方法
6.抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
7.一个类可以实现多个接口,但只能继承一个抽象类。

扩展:
1、接口中可以有非抽象的方法,比如default方法(Java 1.8)。
2、接口中可以有带方法体的方法。(Java 1.8)
3、接口中的方法默认是public的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值