抽象类
在Java中,你可以只给出方法的定义不去实现方法的具体事物,由子类去根据具体需求来具体实现。这种只给出方法定义而不具体实现的方法被称为抽象方法,包含一个或多个抽象方法的类称为抽象类。
举个例子来说:一个图形类应该有面积的方法,但是不同的图形求面积方法不一样。分析事物,发现共性,就出现了向上抽取。
方法的声名相同,但是方法功能主体不同,这样就可以抽取,但只是抽取方法声名,但不抽取方法主体,称这个方法就是抽象方法。
- 方法前加上 abstract 关键字, 表示这是一个抽象方法,抽象方法是没有方法体的,在代码的表达上就是没有“{}”。
- 包含抽象方法的类, 必须加上 abstract 关键字表示这是一个抽象类.
//有抽象方法的类也必须被声明为abstract
abstract class Shape {
//抽象方法,不能有“{}”
abstract public void draw();
}
- 抽象类不能直接实例化.
- 抽象方法不能是 private 的
- 抽象类中可以包含其他的非抽象方法, 也可以包含字段. 这个非抽象方法和普通方法的规则都是一样的, 可以被重写,也可以被子类直接调用
//抽象类
abstract class People{
//抽象方法
public abstract void work();
}
class Doctor extends People{
private String work;
public Doctor(String work) {
this.work=work;
}
//重写方法
@Override
public void work() {
System.out.println("我的职业是"+this.work);
}
}
class Lawyer extends People {
private String work;
public Lawyer(String work) {
this.work = work;
}
@Override
public void work() {
System.out.println("我的职业是" + this.work);
}
}
public class Solution {
public static void main(String[] args) {
Doctor doctor=new Doctor("医生");
doctor.work();
Lawyer lawyer=new Lawyer("律师");
lawyer.work();
}
}
抽象类的作用:
抽象类存在的最大意义就是为了被继承.抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法。使用抽象类相当于多了一重编译器的校验.
接口
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能).
接口的特点:
1、Java接口中的成员变量默认都是public,static,final类型的(都可省略),必须被显示初始化,即接口中的成员变量为常量(大写,单词之间用"_"分隔)
2、Java接口中的方法默认都是public,abstract类型的(都可省略),没有方法体,不能被实例化
3、Java接口中只能包含public,static,final类型的成员变量和public,abstract类型的成员方法
4、接口中没有构造方法,不能被实例化
5、一个接口不能实现(implements)另一个接口,但它可以继承多个其它的接口
6、Java接口必须通过类来实现它的抽象方法
7、当类实现了某个Java接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象类
8、不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例
9、一个类只能继承一个直接的父类,但可以实现多个接口,间接的实现了多继承.
实现多个接口
有的时候我们需要让一个类同时继承自多个父类. 这件事情在有些编程语言通过 多继承 的方式来实现的.
然而 Java 中只支持单继承, 一个类只能 extends 一个父类. 但是可以同时实现多个接口, 也能达到多继承类似的效果.
现在我们通过类来表示一组动物。
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
}
//提供一组接口, 分别表示 "会飞的", "会跑的", "会游泳的"
interface IFlying {
void fly();
}
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
//创建几个具体的动物
//猫跑
class Cat extends Animal implements IRunning {
public Cat(String name) {
super(name);
}
@Override
public void run() {
System.out.println(this.name + "正在用四条腿跑");
}
}
//鱼游
class Fish extends Animal implements ISwimming {
public Fish(String name) {
super(name);
}
@Override
public void swim() {
System.out.println(this.name + "正在用尾巴游泳");
}
}
//青蛙跑和游
class Frog extends Animal implements IRunning, ISwimming {
public Frog(String name) {
super(name);
}
@Override
public void run() {
System.out.println(this.name + "正在往前跳");
}
@Override
public void swim() {
System.out.println(this.name + "正在蹬腿游泳");
}
}
//鸭子跑、飞、游
class Duck extends Animal implements IRunning, ISwimming, IFlying {
public Duck(String name) {
super(name);
}
@Override
public void fly() {
System.out.println(this.name + "正在用翅膀飞");
}
@Override
public void run() {
System.out.println(this.name + "正在用两条腿跑");
}
@Override
public void swim() {
System.out.println(this.name + "正在漂在水上");
}
}
public class Solution {
public static void main(String[] args) {
Cat cat = new Cat("小猫");
cat.run();
Fish fish = new Fish("小鱼");
fish.swim();
Frog frog = new Frog("青蛙");
frog.run();
frog.swim();
Duck duck = new Duck("鸭子");
duck.run();
duck.swim();
duck.fly();
}
}
时刻牢记多态的好处, 忘记类型. 有了接口之后, 类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力。
接口间的继承
接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字.
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}
通过接口继承创建一个新的接口 IAmphibious 表示 “两栖的”. 此时实现接口创建的 Frog 类, 就继续要实现 run 方法,
也需要实现 swim 方法。
抽象类和接口的区别
区别 | 抽象类(abstract) | 接口(interface) |
---|---|---|
结构组成 | 普通类+抽象方法 | 抽象方法+全局常量 |
权限 | public | 各种权限 |
子类使用 | 使用extends关键字继承抽象类 | 使用implements关键字实现接口 |
关系 | 一个抽象类可以实现多个接口 | 接口不能继承抽象类,但接口可以使用extends关键字继承多个父接口 |
子类限制 | 一个子类只能继承一个抽象类 | 一个子类可以实现多个接口 |
来源:CSDN
作者:小仙女
链接:https://blog.csdn.net/weixin_44945537/article/details/104523802