面向对象-抽象类和接口

本文探讨了抽象类和接口在面向对象编程中的角色。抽象类不能被实例化,包含抽象方法,需要子类覆盖才能实例化。final关键字修饰的类和方法不可被继承或覆盖,常用于创建常量。接口作为抽象类的延伸,提供纯粹的抽象方法,支持多实现,降低了耦合性,是功能扩展和规则定义的手段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

抽象类

特点:
1、方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰。抽象方法必须定义在抽象类当中,该类也必须被abstract修饰;
2、抽象类不能被实例化,因为调用抽象方法没有意义;
3、抽象类必须有其子类覆盖了所有的抽象方法,该子类才可以实例化,否则,这个类还是抽象类。
五个问题:
1、抽象类中有构造函数吗?
虽然抽象类不可以被实例化,不能创建对象,但是抽象类中也有构造函数,用于给子类对象进行初始化。
2、抽象类可以不定义抽象方法吗?
抽象类中可以不定义抽象方法,但是很少见,目的就是不让该类创建对象,AWT的适配器对象就是这种类。通常这个类中的方法有方法体,但是却没有内容(其实有隐式语句return;)。
3、抽象类不可以与哪些关键字共存?
private:因为私有的方法不能被子类访问到,子类就不能覆盖抽象方法;
static:因为静态修饰的类可以直接类名调用,不需要对象,但是这种类名调用抽象方法没有意义(没方法体);
final:因为final修饰的方法不能被覆盖,而abstract方法必须被覆盖;在类名出修饰的final也不可以共存,因为抽象类必须被继承,而final类不能被继承。
4、抽象类和一般类的区别。
相同点:都是用来描述事物的,都在内部定义了成员。
不同点:
一般类有足够的信息描述事物,而抽象类描述事物的信息可能不足;
一般类不能定义抽象方法,只能定义非抽象方法,而抽象类可以定义抽象方法和非抽象方法;
一般类可以实例化,抽象类不可以实例化。
5、抽象类一定是个父类吗?
抽象类一定是父类,因为需要子类来覆盖其抽象方法后才可以对子类进行实例化。

final关键字

final关键字,是一个修饰符。其特性有:
1、final可以修饰类、方法、变量;
2、final修饰的类不可以被继承;(当类中所以的方法都不可以被覆盖时,用final修饰合格类。)
3、final修饰的方法不可以被覆盖;
4、final修饰的变量是一个常量,只能赋值一次;
5、final修饰的变量必须显式初始化。
一般来说,被final修饰了,也会被static修饰。
为什么用final修饰变量?
虽然可以直接用这个固定的数据,但是可读性查,所以取个名称,且这个名称不能变化,所以加上final固定。
写法规范:常量所有字母都大写,多个单词中间用下划线“_”连接。
抽象类示例:

/**
雇员示例:
需求:公司中程序员有姓名,工号,薪水,工作内容。
项目经理除了有姓名,工号,薪水,还有奖金,工作内容。
对给出需求进行数据建模。


分析:
在这个问题领域里,先找出涉及的对象。
通过名词提炼法。
程序员:
    属性:姓名,工号,薪水
    行为:工作
经理:
    属性:姓名,工号,薪水,奖金
    行为:工作

程序员和经理不存在直接继承关系,但是程序员和经理却具有着共性的内容。可以进行抽取,因为他们都是公司的雇员,可以将程序员和经理进行抽取,建立体系。
*/
//描述雇员。
class Employee
{
    private String id;
    private String name;
    private double pay;
    Employee(String name,String id,double pay)
    {
        this.name=name;
        this.id=id;
        this.pay=pay;
    }
    pulic abstract void work();
}

//描述程序员
class Programmer extends Employee
{
    Programmer(String name,String id,double pay)
    {
        super(name,id,pay);   //调用父类的构造函数完成初始化
    }
    public void work()
    {
        System.out.println("code...");
    }
}

//描述经理
class Manager extends Employee
{
    private int bonus;
    Manager(String name,String id,double pay,int bonus)
    {
        super(name,id,pay);//调用父类的构造函数初始化
        this.bonus=bonus;//完成自己特点的初始化
    }
    public void work()
    {
        System.out.println("manage");
    }
}

接口

简介
接口是抽象类的延伸,可以将其看做纯粹的抽象类,接口中的所以方法都没有方法体。接口的出行将多继承通过另一种形式体现出来,即“多实现”。
定义接口使用的关键字不是class,是interface,虽然定义的关键字不是class,但是编译后生成的文件还是class文件,因为java最终都是以class文件来封装字节码数据的。

对于接口中常见的成员:
接口中成员的修饰符都是固定的。
1.全局常量:public static final
2.抽象方法:public abstract
如果忘了加这些修饰符,会自动给加上,只要有interface关键字,里面的成员修饰符会固定。但是不写这些修饰符的话,可读性很差。
可见,接口中的成员都是公共的权限。权限都是最大的。

类与类之间之间是继承关系,类与接口之间是实现关系。
接口不可以实例化,只能由实现了接口的子类并覆盖了接口中所有的抽象方法后,该子类才可以实例化,否则,这个子类就是一个抽象类。

在java中不直接支持多继承,因为会出现调用的不确定性。所以java将多继承机制进行改良,在java中变成了多实现。由于接口里的函数都要被覆盖,即使是不同接口存在一模一样的函数也不会有调用的不确定性。一个类可以实现多个接口。此外,一个类在继承另外一个类的同时,还可以实现多个接口。接口的出现避免了单继承的局限性。接口与接口之间是继承关系,而且接口可以多继承,因为接口中方法没有方法体。

接口的特点:
1、接口是对外暴露的规则
2、接口是程序的功能扩展
3、接口的出现降低耦合性
4、接口可以用来多实现
5、类与接口之间是实现关系,而且类可继承一个类的同时实现多个接口
6、接口与接口之间可以有继承关系

抽象类和接口的异同点:
相同:都是不断向上抽取而来的。
不同: 1.抽象类需要被继承,而且只能单继承;接口需要被实现,而且可以多实现。
2.抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法;接口中只能定义抽象方法,必须由子类去实现。
3.抽象类的继承是is a 关系,在定义该体系的基本共性内容;接口的实现是like a关系,在定义体系外额外功能。

abstract class dog //seeing eye dog is a dog:体系的基本共性内容
{
    public abstract void wangwang();
}   
interface daomang//seeing eye dog is daomangable:体系外额外功能
{
    public abstract void daomang();
}
class daomangdog extends dog implements daomang
{
    public void wangwang()//子类里覆盖所有的抽象方法
    {}
    public void daomang()
    {}
}

接口示例

interface Demo
{
    public  static final int NUM=4;
    abstract void show1();//没有方法体
    abstract void show2();
}

//类与类之间之间是继承关系,类与接口之间是实现关系
class DemoImpl implements Demo
{
    public void show1()
    {}//有方法体
    public void show2()
    {}
}

class InterfaceDemo
{
    public static void main(String[] args)
    {
        DemoImpl d=new DemoImpl();
        //以下这三种调用方式都正确
        System.out.println(d.NUM);//对象名调用
        System.out.println(DemoImpl.NUM);//类名调用
        System.out.println(Demo.NUM);//接口名调用
    }   
}
/*
笔记本电脑使用
为了扩展笔记本的功能,但日后出现什么功能设备不知道。
定义一个规则,只要日后出现的设备都符合这个规则就可以了。
规则在java中就是接口。
*/

//接口
interface USB//暴露的规则
{
    public void open();
    public void close();

}

//笔记本电脑
class BookPC
{
    public static void main(String[] args)
    {
        useUSB(new Mouse());//功能扩展了
        useUSB(new Keyboard());
    }

    //使用规则
    public static void useUSB(USB u)//u是接口类型的变量,是 一个引用变量。接口类型的引用,用于接收(指向)接口的子类对象
    {
        u.open();
        u.close();
    }
}

//实现规则
//这些设备和电脑的耦合性降低了
//实现usb接口的设备
class Mouse implements USB
{
    public void open()//覆盖抽象方法
    {
        System.out.println("Mouse open");
    }
    public void close()
    {
        System.out.println("Mouse close");
    }
}
//实现usb接口的设备
class Keyboard implements USB
{
    public void open()//覆盖抽象方法
    {
        System.out.println("Keyboard open");
    }
    public void close()
    {
        System.out.println("Keyboard close");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值