一.抽象类
观察代码:
class Shape{
public void draw(){
//啥都不干
}
}
class Cycle extends Shape{
@Override
public void draw() {
System.out.println("⚪");
}
}
class Rect extends Shape{
@Override
public void draw() {
System.out.println("♦");
}
}
public class Test {
public static void main(String[] args) {
Shape shape1=new Cycle();
Shape shape2=new Rect();
shape1.draw();
shape2.draw();
}
}
//打印结果
⚪
♦
上述代码中,父类Shape中的draw方法并没有什么实际的工作,主要绘制图形都是由子类的draw方法来完成的。像这样的没有实际工作的方法,就可以将它设计为一个抽象方法。
abstract class Shape{
abstract public void draw();
}
1.在draw方法前加上abstract关键字,表示这是一个抽象方法,抽象方法没有方法体,不能执行具体的代码。
2.对于包含抽象方法的类,系统将强制要求该类被声明为抽象类
注意事项:
1.抽象类不可以被实例化
2.抽象方法不能是private的
3.抽象类中可以包含其他的非抽象方法,也可以包含字段,这个非抽象方法和普通方法的规则是一样的,可以被重写也可以被子类直接调用
抽象类的特点:
①包含抽象方法的类叫抽象类(抽象类中不一定含有抽象方法)
②抽象类不能被实例化,要想使用,只能创建该类的子类,然后让子类重写抽象类中的抽象方法
③抽象类中可以有抽象方法,也可以有普通方法或成员变量
④只要继承抽象类,子类就一定要重写抽象类里的抽象方法
⑤抽象类A如果继承了抽象类B,类A可以选择重写或者不重写抽象类B中的方法
二.接口
接口,比抽象类更加抽象,抽象类中可以包含非抽象方法,而接口中都是抽象方法,字段只能是静态常量。
观察代码:
interface Ishape{ //定义接口
void draw();
}
class Cycle implements Ishape{ //实现接口
@Override
public void draw(){
System.out.println("⚪");
}
}
public class Test{
public static void main(String[] args) {
Ishape shape=new Cycle();
shape.draw();
}
}
//打印结果
⚪
1.使用interface定义一个接口
2.接口中的方法一定是抽象方法,因此可以省略abstract
3.接口中的方法一定是public,因此可以省略public
4.Cycle使用implements实现接口
5.在调用时可以创建一个接口的引用,对应到一个子类的实例
6.接口不能被单独实例化
7.接口可以同时实现多个
8.只要普通类实现这个接口,那么接口中的方法都必须重写
9.接口和接口之间是继承关系,接口可以多继承(接口间的继承相当于把多个接口合并在一起)
实现多个接口
在Java中只支持单继承,但是可以实现多个接口,也能达到多继承类似的效果
代码举例:
class Animal{
protected String name;
public Animal(String name){
this.name=name;
}
}
//定义三个接口
interface Iflying{
void fly();
}
interface Irunning{
void run();
}
interface Iswimming{
void swim();
}
//Cat类继承Animal类并且实现Irunning接口
class Cat extends Animal implements Irunning{
public Cat(String name){
super(name);
}
@Override
public void run() {
System.out.println(this.name+"running");
}
}
//Fish类继承Animal类并且实现Iswimming接口
class Fish extends Animal implements Iswimming{
public Fish(String name){
super(name);
}
@Override
public void swim() {
System.out.println(this.name+"swimming");
}
}
//Duck类继承Animal类并且实现Irunning,Iflying,Iswimming三个接口
class Duck extends Animal implements Irunning,Iflying,Iswimming{
public Duck(String name){
super(name);
}
@Override
public void swim() {
System.out.println(this.name+"swimming");
}
@Override
public void run() {
System.out.println(this.name+"running");
}
@Override
public void fly() {
System.out.println(this.name+"flying");
}
}
public class Test{
//实现一个方法叫散步
public static void walk(Irunning running){
System.out.println("散步");
running.run();
}
public static void main(String[] args) {
Cat cat=new Cat("小猫");
walk(cat);
Duck duck=new Duck("可达鸭");
walk(duck);
}
}
//打印结果
散步
小猫running
散步
可达鸭running
在上述代码walk方法内部,并不需要关心到底是哪种动物,只要参数是会跑的就行
注意: 一个类要先继承另一个类然后再实现接口,接口可以实现多个,接口名之间用逗号隔开即可。
小结:
两者核心区别:
抽象类中可以有普通方法和普通字段,这样的普通方法和字段可以被子类直接调用,而在接口中不能包含普通方法,子类必须重写所有的抽象方法