文章目录
一.抽象类
概念
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
抽象类的特点
- 抽象类和抽象方法必须使用abstract关键字修饰
- 抽象类格式:
abstract class 类名{}
- 抽象方法格式:
public abstract void 方法名();
- 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
- 抽象类不能进行实例化,但抽象类中可以有构造方法,目的是用于子类访问父类数据时的初始化
- 抽象类不能直接实例化,是按照多态的方式,由具体的子类实例化。
- 抽象类的子类
- 要么是抽象类
- 要么必须重写抽象类中的所有抽象方法
举例:抽象类的简单定义
//抽象类的定义
public abstract class Animals {
String name;
int age;
//共性功能定义为抽象的,抽象类只需给出共性的声明即可
// 具体的实现细节由子类根据自身的差异性,具体去重写
public abstract void eat();
public abstract void sleep();
public void show(){
System.out.println("抽象类内可以有非抽象方法");
}
}
//子类继承该抽象类,必须重写抽象类中的抽象方法
public class Cat extends Animals {
//抽象方法的重写,由子类依据自身特性具体实现
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫睡沙发");
}
}
public class Dog extends Animals {
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void sleep() {
System.out.println("狗睡地上");
}
}
抽象类的成员特点
- 成员变量:既可以是变量,也可以是常量
- 构造方法:有,用于子类访问父类数据的初始化。
- 成员方法:既可以是抽象的,也可以是非抽象的。
注意
抽象类的成员方法特性:
- 抽象方法 强制要求子类做事情
- 非抽象方法 子类继承的事情,提高代码复用性
举例:抽象类如何实例化
public class Mytest {
public static void main(String[] args) {
//采用多态的形式创建父类引用,间接实例化父类
Fu fu=new Zi();
//多态中成员变量的访问特点:编译看左,运行看左
System.out.println(fu.num);
//多态中成员方法的访问特点:编译看左,运行看右
fu.show();
//向下转型,将父类引用强制转化成子类引用
Zi zi=(Zi)fu;
System.out.println(zi.num);
zi.show();
}
}
abstract class Fu{
int num=10;
//抽象类不能直接实例化,但是有构造方法
public Fu(){
System.out.println("父类构造方法执行");
}
public abstract void show();
}
class Zi extends Fu{
int num=20;
public Zi(){
System.out.println("子类构造方法执行");
}
@Override
public void show() {
System.out.println("子类show方法执行");
}
}
运行结果:
思考
-
一个类如果没有抽象方法,可不可以定义为抽象类?
可以,外界不能创建该类对象,相当于私有化类的构造方法。
-
abstract不能和哪些关键词共存?
- final:矛盾,abstract强制子类必须重写,final不允许子类重写
- private:矛盾,abstract强制子类必须重写,private子类无法继承,也就无法重写
- static:静态方法属于类,故不参与重写,无意义
练习
需求:假如我们在开发一个系统时需要对员工(Employee)类进行设计,员工包含3个属性:姓名、工号以及工资(salary)。
经理(Manager)也是员工,除了含有员工的属性外,另为还有一个奖金(bonus)属性。 然后定义工作的方法.
请使用继承的思想设计出员工类和经理类。
//定义一个抽象类,将员工和经理的共性抽取出来,并声明一个抽象方法。
public abstract class person {
public String name;
public int num;
public double salary;
public abstract void workshow();
}
//员工类继承该抽象类,并依据自身的特性,实现抽象类中的抽象方法
public class Employee extends person {
@Override
public void workshow() {
System.out.println("员工一周工作七天");
}
}
//经理继承该抽象类,并重写抽象方法。声明额外属性bouns
public class Manager extends person{
public double bouns;
@Override
public void workshow() {
System.out.println("经理一周工作5天");
}
}
//测试类
public class Mytest {
public static void main(String[] args) {
//使用多态的方式,创建对象
person p=new Employee();
p.name="小明";
p.num=224075;
p.salary=3500;
System.out.println("员工名字:"+p.name+";职工号:"+p.num+";月薪:"+p.salary);
//多态中成员方法的访问特点:编译看左,运行看右
p.workshow();
System.out.println("====================================================");
person p1=new Manager();
p1.name="赵建国";
p1.num=1;
p1.salary=7500;
//向下转型,才能调用子类中的特有属性
((Manager) p1).bouns=800;
System.out.println("经理名字:" + p1.name + ";职工号:" + p1.num + ";月薪:" + p1.salary+";奖金:"+((Manager) p1).bouns);
p1.workshow();
}
}
运行结果:
二. 接口
概念
为了体现事物功能的扩展性,Java中提供了接口来定义这些额外功能,并不给出具体实现,交由某些具体对象将这些额外功能实现即可。
接口的特点
- 接口用关键字 interface 格式:
interface 接口名{}
- 类实现接口用implements 格式:
class 类名 implements 接口名{}
- 接口不可以直接实例化,需要按照多态的方式进行实例化
- 接口的子类
- 可以是抽象类,但意义不大
- 可以是具体类。要重写接口中的所有抽象方法。
接口成员的特点
- 成员变量:只能是常量,并且是静态的。默认修饰符:public static final(建议手动给出)
- 构造方法:接口没有构造方法
- 成员方法:只能是抽象方法,默认修饰符:public abstract(建议手动给出)
举例:接口的简单定义及实现
//定义一个接口,接口中定义的都是一些扩展功能,哪类事物需要具备该扩展功能,就需要实现该接口。
public interface Myinterface {
public static final int num=1000;//默认修饰符:public static final
public abstract void calc();//默认修饰符:public abstract
}
//子类实现父接口,必须重写接口中的所有抽象方法
public class person implements Myinterface {
@Override
public void calc() {
System.out.println("人会算数");
}
public void love(){
System.out.println("人有情感");
}
}
public class dog implements Myinterface {
@Override
public void calc() {
System.out.println("狗经过后天训练,也会算数");
}
public void watchdoor(){
System.out.println("狗会看家");
}
}
//使用多态的形式,创建对象。
public class mytest {
public static void main(String[] args) {
//接口不能创建对象,子类和接口之间是实现关系,可以叫父接口,子类
//采用多态的形式
Myinterface myinterface=new person();
myinterface.calc();
System.out.println(myinterface.num);
//想要调用子类中独有的方法,需向下转型
person p=(person)myinterface;
p.love();
System.out.println(p.num);
System.out.println("=====================================");
Myinterface myinterface1 = new dog();
myinterface1.calc();
System.out.println(myinterface1.num);
dog d=(dog)myinterface1;
d.watchdoor();
System.out.println(d.num);
}
}
三. 抽象类和接口的区别
-
成员区别
-
抽象类
- 成员变量:可以是变量,也可以是常量
- 构造方法:有
- 成员方法:可以是抽象方法,也可以是非抽象
-
接口
- 成员变量:必须是公共的静态常量 默认修饰public static final
- 成员方法:只能是抽象方法 JDK1.8之后可以定义default修饰方法,可以给出功能的具体实现,子类可以继承下去用,JDK1.8之后再接口中也可以定义静态方法。
-
-
关系区别
-
类与类
- 继承,单继承,多层继承
-
类与接口
- 实现,单实现,多实现
-
接口与接口
- 继承,单继承,多继承
-
-
设计理念区别
- 抽象类,被继承体现的是“is a"的关系,抽象类中定义的是该继承体系的共性功能
- 接口,被实现体现的是”like a“的关系,接口中定义的是该继承体系的扩展功能。