并没有那么多天赋异禀
优秀的人总是努力翻山越岭
1.抽象类
1.1 抽象类的概念
class Animal {
public String name;
public void bark() {
System.out.println(name+"叫");
}
}
class Dog extends Animal {
public void bark() {
System.out.println(name+"汪汪汪");
}
}
class Cat extends Animal {
public void bark() {
System.out.println(name+"喵喵喵");
}
}
- 狗、猫都属于动物,所以狗类、猫类都需要继承动物类。那么动物类就是父类,狗类、猫类都是子类
- 在动物类中每一种动物的叫声都是不一样的,所以动物类中 bark 方法无法具体实现,需要在子类当中重写 bark 方法
- 那么我们就可以把 Animal 设置为抽象类
我们现在知道了抽象类使用的场景,那我们接下来就具体谈谈什么是抽象类:
我们知道在面向对象的世界里,一切皆为对象,对象是通过类来描述的。如果一个类中没有足够的信息来描绘一个具体的对象,那么这样的类就是抽象类
就像上述在动物类的例子中,我们可以发现,父类** Animal 中的 bark **方法好像没有什么实际工作,主要由 Animal 的各种子类的 bark 方法来完成。像这种没有什么实际工作的方法,我们可以将其设置为抽象方法,包含抽象方法的类我们就称为抽象类
1.2 抽象类的语法
在 Java 中,**被 abstract 修饰的类就叫做抽象类 **
**在抽象类中被 abstract 修饰的方法就叫做抽象方法,抽象方法不用给出具体的实现体 **
//被abstract修饰的类就叫做抽象类
abstract class Animal {
public String name;
Animal(String name) {
this.name = name;
}
abstract public void bark();//被abstract修饰的方法就叫做抽象方法
}
class Dog extends Animal {
Dog(String name) {
super(name);
}
public void bark() {
System.out.println(name+"汪汪汪");
}
}
- abstract 修饰的类就是抽象类
- abstract 修饰的方法就是抽象方法
- 抽象类也是类,里面可以包含普通方法和属性,甚至构造方法
- 抽象方法没有实现体
- 抽象类的子类必须重写抽象类中的抽象方法 ,否则直接报错
- 抽象类的子类如果也是抽象类则不用重写抽象方法
1.3 抽象类的特性
abstract class Animal {
public String name;
abstract public void bark();
}
class Dog extends Animal {
public void bark() {
System.out.println(name+"汪汪汪");
}
}
class Cat extends Animal {
public void bark() {
System.out.println(name+"喵喵喵");
}
}
我们通过上述类的代码来谈谈抽象类的特性
**①抽象类不能直接实例化 **
②抽象方法不能是 private 修饰(抽象方法如果没有加访问限定符时,默认是public)
**③抽象方法不能被 final 和 static 修饰,因为抽象方法要被子类重写 **
④抽象类必须被继承,并且继承后子类要重写父类中的抽象方法(否则子类也是抽象类,必须要使用 abstract 修饰)
abstract class Animal {
public String name;
abstract public void bark();
}
class Dog extends Animal {
public void bark() {
System.out.println(name+"汪汪汪");
}
}
abstract class Animal {
public String name;
abstract public void bark();
}
abstract class Dog extends Animal {
}
注:当有其他类继承 Dog 类,还是必须重写 Animal 类中的抽象方法
**⑤抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类 **
**⑥抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量 **
1.4 抽象类的作用
介绍完上述的抽象类后,想必大家此时都有这样一个疑问:抽象类可以实现的普通类也可以实现呀,抽象类可以被继承普通类也可以被继承,抽象类需要实现方法的重写,普通类也可以实现方法的重写,那究竟为什么需要抽象类呢?
那现在给大家举个例子,想必大家也就明白了为什么需要抽象类了
比如:上述我们讲的动物类,每个动物都会叫,但是不同的动物叫声都不一样。那么在 Animal 动物类中就无法具体实现 bark 方法 ,我们就可以将 bark 方法设置为抽象方法,那么 Animal 类也就需要设置为抽象类。我们上述讲抽象类的特性时也就强调过普通类继承抽象类一定要重写抽象类中的抽象方法,如果不重写抽象类中的抽象方法就会直接报错。那么普通类必须重写抽象类中的抽象方法这就起到一种校验的作用,这样也就避免了用户忘记重写抽象方法而导致出错
2.接口
2.1 接口的概念
说到接口,大家可以想到什么呢?
比如生活中常见的插座的插孔,电脑上常有的USB接口等等。这些都属于接口
插座插孔可以接所有符合规范的设备,电脑的USB接口可以接所有符合USB协议的设备
**接口的概念:接口就是公共的行为规范标准,用户在实现时,只要符合规范标准,就可以通用 **
在Java中,接口可以看成是:**多个类的公共规范,是一种引用数据类型 **
2.2 接口的语法规则
**interface 修饰的就是接口 **
建议:
- 在创建接口时,接口的命名一般以大写字母 I 开头
- 接口的命名一般使用 "形容词" 词性的单词
- 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性
- interface 修饰的是接口
- 接口中定义的变量不加 public static final 默认也是 public static final 修饰,建议不要加保持代码的简洁性
- 接口中的抽象方法不加 public abstract 默认也是 public abstract 修饰,建议不要加保持代码的简洁性
- jdk1.8 开始,允许在接口中可以实现方法,但必须有 default 修饰
- 接口当中可以实现静态方法
2.3 接口的使用
接口不能直接使用,那么也就不能 new 一个接口 。接口需要通过类来实现,实现接口当中的所有抽象方法。类需要通过 implements 来实现接口
注:子类与父类之间是 extends 继承关系,类与接口之间是 implements 实现关系
interface IDome {
int number = 1;
void fun();
default void fun2() {
System.out.println("fun2");
}
static void fun3() {
System.out.println("fun3");
}
}
class Dome implements IDome {
//需要实现接口中的抽象方法
public void fun() {
System.out.println("fun");
}
}
public class Test {
public static void main(String[] args) {
Dome dome = new Dome();
System.out.println(dome.number);
dome.fun();
dome.fun2();
IDome.fun3();
}
}
2.4 接口的属性
interface IDome {
int number = 1;
void fun();
}
class Dome implements IDome {
//需要实现接口中的抽象方法
public void fun() {
System.out.println("fun");
}
}
我们通过这个代码来,说说接口的属性
**①接口类型是一种引用类型,但是不能直接new接口的对象 **
**②接口中每一个方法都是 public 的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错) **
**③接口中的方法是不能在接口中实现的,只能由实现接口的类来实现 **
④重写接口中方法时,不能使用 default 访问权限修饰
编译报错,重写** IDome** 中** fun **方法时,不能使用默认修饰符
**⑤接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量 **
因为** number **是 **public static final **修饰的,所以它无法重新赋值
**⑥接口中不能有静态代码块和构造方法 **
**⑦接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class **
**⑧如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类 **
⑨jdk8中:接口中还可以包含default方法
2.5 实现多个接口
在Java中,类和类之间是单继承的,一个类只能有一个父类,即Java中不支持多继承。但是一个类可以实现多个接口。
**一个类实现多个接口的语法格式: **
interface IFlying {
void fly();
}
interface IRuning {
void run();
}
interface ISwimming {
void swim();
}
class Animal {
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
}
class Duck extends Animal implements IFlying,IRuning,ISwimming {
public Duck(String name, int age) {
super(name, age);
}
public void fly() {
System.out.println(name+age+"会飞");
}
public void run() {
System.out.println(name+age+"会跑");
}
public void swim() {
System.out.println(name+age+"会游泳");
}
}
public class Test {
public static void main(String[] args) {
Duck duck = new Duck("小黄鸭",2);
duck.run();
duck.fly();
duck.swim();
}
}
运行结果:
- 一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类。
- 一个类只能继承一个父类, 但是可以同时实现多种接口
2.6 接口中的继承
在Java中,类和类之间是单继承的,一个类可以实现多个接口,接口与接口之间可以多继承。即:用接口可以达到多继承的目的
接口可以继承一个接口, 达到复用的效果. 使用** extends **关键字
interface Runing {
void run();
}
interface Swimming {
void swim();
}
interface Amphibian extends Runing,Swimming {
}
class Zoon implements Amphibian {
public void run() {
System.out.println("跑");
}
public void swim() {
System.out.println("游");
}
}
public class Test {
public static void main(String[] args) {
Zoon zoon = new Zoon();
zoon.swim();
zoon.run();
}
}
当 **Zoom 类实现 Amphibian **接口时,需要重写 **run 方法和 swim **方法。因为接口继承了接口, 达到复用的效果
接口间的继承相当于把多个接口合并在一起
2.7 抽象类和接口的区别
抽象类和接口都是 Java 中多态的常见使用方式
相同点:
- 都是 abstract 修饰的
- 里面都可以有抽象方法,被其他类继承或者实现 时都需要重写(除了抽象类以外不需要重写)
不同点:
- 抽象类是类,是被其他类继承的
- 接口是接口,是被其他类实现的
- 抽象类中可以包含普通方法和普通字段 ,这样普通方法和普通字段可以被子类直接使用
- 接口中不能有普通方法,除非普通方法前面加上 default
- 抽象类可以有构造方法
- 接口不能有构造方法
抽象类存在的意义是为了让编译器更好的校验,像 Animal 这样的类我们并不会直接使用,而是使用它的子类,要是创建了 Animal 的实例,编译器会及时提醒我们
抽象类和接口的区别图:
版权归原作者 拼命阿紫 所有, 如有侵权,请联系我们删除。