22 抽象类
22.1 抽象类概述
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类
例:抽象类和抽象方法定义,需要用abstract关键字
package myAbstract.Demo1; public abstract class Animal { // public void eat(){ // System.out.println("吃东西"); // } public abstract void eat(); //抽象方法 }
22.2 抽象类的特点
- 抽象类和抽象方法必须使用abstract关键字修饰
public abstract class 类名{} public abstract void eat();
- 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 抽象类不能实例化
抽象类如何实例化?
参照多态的方式,通过子类对象实例化,这叫抽象类多态
代码如下:
Animal.java
package myAbstract.Demo2; //抽象方法的类一定是抽象类 //抽象类里面不一定要抽象方法 public abstract class Animal { //抽象类 public abstract void eat(); //抽象方法 public void sleep(){ System.out.println("睡觉"); } }
Cat.java
package myAbstract.Demo2; public class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } }
Dog.java
package myAbstract.Demo2; public abstract class Dog extends Animal{ }
AnimalDemo.java
package myAbstract.Demo2; public class AnimalDemo { public static void main(String[] args) { Animal a = new Cat(); a.eat(); a.sleep(); System.out.println("----------------"); Cat b = new Cat(); b.eat(); b.sleep(); } }
22.3 抽象类的成员特点
- 成员变量:可以是变量,也可以是常量
- 构造方法:有构造方法,但不能实例化。
- 成员方法:可以有抽象方法,用于限定子类必须完成某些动作;也可以有非抽象方法,提高代码复用性
那么,构造方法的作用是什么呢?
用于子类访问父类数据的初始化
Animal.java
package myAbstract.Demo3; //抽象类 public abstract class Animal { private int age = 20; private final String city = "北京"; public Animal(){} public Animal(int age){ this.age = age; } public void show(){ age = 40; //就近 System.out.println(age); System.out.println(city); } public abstract void eat(); }
Cat.java
package myAbstract.Demo3; public class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } }
AnimalDemo.java
package myAbstract.Demo3; //测试类 public class AnimalDemo { public static void main(String[] args) { Animal a = new Cat(); a.eat(); a.show(); } }
案例:猫和狗
Animal.java
package myAbstract.Demo4; //抽象类 public abstract class Animal { private String name; private int age; public Animal() { } public Animal(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public abstract void eat(); }
Cat.java
package myAbstract.Demo4; public class Cat extends Animal{ public Cat() { } public Cat(String name, int age) { super(name, age); } @Override public void eat() { System.out.println("猫吃鱼"); } }
Dog.java
package myAbstract.Demo4; public class Dog extends Animal{ public Dog() { } public Dog(String name, int age) { super(name, age); } @Override public void eat() { System.out.println("狗吃骨头"); } }
AnimalDemo.java
package myAbstract.Demo4; //测试类 public class AnimalDemo { public static void main(String[] args) { Animal a = new Cat(); a.setName("加菲猫"); a.setAge(5); System.out.println(a.getName() + "," + a.getAge()); a.eat(); System.out.println("-----------"); a = new Cat("橘猫", 6); System.out.println(a.getName() + "," + a.getAge()); a.eat(); } }
23 接口
接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用
Java中的接口更多的体现在对行为的抽象
23.1 接口的特点
- 接口用关键字interface修饰,
public interface 接口名{}
- 类实现接口用implements表示:
public class 类名 implements 接口名{}
- 接口不能实例化
接口如何实现实例化?
参照多态的方式,通过实现类对象实例化,这叫接口多态
多态的形式:具体类多态,抽象类多态,接口多态
多态的前提:有继承或者实现关系;有方法重写;有父(类/接口)引用指向(子/实现)类对象
接口的实现类:要么重写接口中的所有抽象方法;要么是抽象类
代码:
Jumpping.java
package myInterface.Demo1; //定义了一个接口 public interface Jumpping { //换了关键字 public abstract void jump(); //public abstract可省略 }
Cat.java
package myInterface.Demo1; public class Cat implements Jumpping{ @Override public void jump() { System.out.println("猫可以调高了"); } }
Dog.java
package myInterface.Demo1; public abstract class Dog implements Jumpping{ }
JumppingDemo.java
package myInterface.Demo1; public class JumppingDemo { public static void main(String[] args) { //Jumpping j = new Jumpping(); //报错 Jumpping j = new Cat(); j.jump(); } }
23.2 接口的成员特点
- 成员变量:只能是常量,默认修饰符
public static final
- 构造方法:接口没有构造方法,因为接口主要是对行为进行抽象的,是没有具体存在的
- 成员方法:只能是抽象方法,默认修饰符
public abstract
关于接口中的方法,JDK8和JDK9中有一些新特性,后面再讲解
Inter.java接口
package myInterface.Demo2; public interface Inter { public int num = 10; public final int num2 = 20; public static final int num3 = 30; //static和final可以不写的,默认有 int num4 = 40; //接口没有构造方法 //public void show(){} public abstract void method(); void show(); }
InterImpl.java
package myInterface.Demo2; //public class InterImpl implements Inter{ public class InterImpl extends Object implements Inter{ //extends Object默认有 public InterImpl(){ super(); } @Override public void method() { System.out.println("method"); } @Override public void show() { System.out.println("show"); } }
InterfaceDemo.java
package myInterface.Demo2; //测试类 public class InterfaceDemo { public static void main(String[] args) { Inter i = new InterImpl(); //接口中成员变量 默认被final修饰,且被static修饰 //i.num = 20; //报错 System.out.println(i.num); System.out.println(Inter.num); System.out.println(i.num2); } }
案例:猫和狗
Jumpping.java接口
package myInterface.Demo3; public interface Jumpping { void jump(); }
Animal.java抽象方法
package myInterface.Demo3; public abstract class Animal { private String name; private int age; public Animal() { } public Animal(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public abstract void eat(); }
Cat.java
package myInterface.Demo3; public class Cat extends Animal implements Jumpping{ public Cat(){} public Cat(String name, int age){ super(name, age); } @Override public void eat() { System.out.println("猫吃鱼"); } @Override public void jump() { System.out.println("猫可以跳高了"); } }
Dog.java
package myInterface.Demo3; public class Dog { }
AnimalDemo.java测试类
package myInterface.Demo3; //测试类 public class AnimalDemo { public static void main(String[] args) { //创建对象 Jumpping j = new Cat(); j.jump(); //j.eat(); //报错 System.out.println("--------------"); Animal a = new Cat("加菲猫", 5); System.out.println(a.getName() + "," + a.getAge()); a.eat(); //a.jump(); //报错 System.out.println("----------------"); Cat c = new Cat("橘猫", 6); c.eat(); c.jump(); } }
23.3 类和接口关系
- 类和类关系:继承关系,只能是单继承,但是可以多层继承
- 类和接口关系:实现关系,但是单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
- 接口和接口关系:继承关系,可以单继承,也可以多继承
Inter1.java接口1
package myInterface.Demo4; public interface Inter1{ }
Inter2.java接口2
package myInterface.Demo4; public interface Inter2 { }
Inter3.java接口3
package myInterface.Demo4; public interface Inter3 extends Inter1, Inter2 { }
InterImpl.java
package myInterface.Demo4; public class InterImpl extends Object implements Inter1, Inter2, Inter3 { }
23.4 抽象类和接口的区别
举例说明:
案例:运动员和教练
代码实现如下:
SpeakEnglish接口
package myInterface.Demo5; //说英语的接口 public interface SpeakEnglish { public abstract void speak(); }
Person抽象类
package myInterface.Demo5; public abstract class Person { private String name; private int age; public Person(){} public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public abstract void eat(); }