这里写目录标题
抽象类
概念与定义
思考:
Animal类的继承体系,有什么问题?
从祖先类开始,随着一个个子类的定义,子类变得越来越具体,而祖先类则更具有一般性和抽象性。
在这种情况下,我们将祖先类设计的更加抽象,只将它作为派生其他类的父类,而不能创造实例
这样的类,我们称之为抽象类,使用关键字abstract(抽象的)标记

但抽象类可以没有抽象方法

abstract关键字:
修饰类:
1,语法:权限修饰符 abstract class 类名 {}
2,表示该类是一个抽象类
修饰成员方法:
1,语法:权限修饰符 abstract 返回值 方法名 () {} ;
2,该方法是一个抽象方法
抽象类的特点



1,抽象类不能实例化,但是开发中会提供子类,可以用多态的方式访问
2,抽象类具有普通构造方法,成员变量和成员方法
3,抽象类中的构造方法是留给子类初始化时调用的
4,抽象类中可以没有抽象方法
抽象类的成员特点

总结抽象类成员特点:
1,构造方法:同普通类
2,成员变量:同普通类
3,成员方法:可以是抽象方法,也可以是非抽象方法


抽象类猫和狗案例

Animal
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
public class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
Dog
public class Dog extends Animal {
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
AnimalDemo
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("加菲",5);
System.out.println(a.getName()+","+a.getAge());
a.eat();
}
}

抽象类的子类的特点
1,抽象类的子类可以是抽象类,也可以是具体类
2,只有当子类重写了所有的继承自抽象类的方法,该子类才能被定义为具体类
3,反之,若任一抽象方法没有被重写,该类都必须定义为抽象类
抽象方法的特点
1,抽象方法没有方法体,只有方法声明,不要忘记分号
2,抽象方法必须在一个抽象类中
abstract使用上的注意点
1,不能用来修饰构造器、属性、代码块等结构
2,不能用来修饰final类
3,不能用来修饰私有方法、静态方法 、final方法
4,一个抽象类中可以没有抽象方法,但是意义不是很大
接口
回想Animal继承体系的案例,现在我们把Animal设计成抽象类后
有了新的需求:
现在有一批猫和狗,经过了特殊训练,猫和狗都可以直立行走(Wlak Upright)和骑自行车(Ride Bike)
怎么去描述这群动物?
这群猫狗,抽取出他们共有的特殊技能,然后继承,但是Java并不支持多继承,我们以往的知识已经不能处理这种情况
接口的概念
一方面,我们有时需要从多个类中派生出一个类,继承它们所有的成员,Java语法不适用
另一方面,我们有时候需要从几个类中抽取出共同的行为特征,而它们之间并没有“is-a”关系,继承思想显得不适用
于是我们引入接口这种数据类型
接口概述
1,语法:权限修饰符 interface 接口名 {}
2,接口不是类,而是一种独立的数据类型,和class并列
3,类“继承”接口,称之为实现,使用implements关键字
格式:class 类名 implements 接口名 {}
4,类永远是先继承再实现
接口的特点



接口的成员特点



1,接口中没有构造器,接口不能实例化
2,接口中的所有成员变量都默认是由public static final修饰的
3,接口中的所有抽象方法都默认是由public abstract修饰的
4,接口与接口之间支持多继承
接口版猫和狗案例

Jumpping
public interface Jumpping {
public abstract void jump();
}
Animal
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
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("猫可以跳高了");
}
}
AnimalDemo
public class AnimalDemo {
public static void main(String[] args) {
//创建对象,调用方法
Jumpping j = new Cat();
j.jump();
System.out.println("--------");
Animal a = new Cat();
a.setName("加菲");
a.setAge(5);
System.out.println(a.getName()+","+a.getAge());
a.eat();
// a.jump();//抽象类的多态实现,不能使用接口类中的方法
a = new Cat("加菲",5);
System.out.println(a.getName()+","+a.getAge());
a.eat();
System.out.println("--------");
Cat c = new Cat();//具体类的实现
c.setName("加菲");
c.setAge(5);
System.out.println(c.getName()+","+c.getAge());
c.eat();
c.jump();
}
}

类和接口的关系


接口和类的区别


改进

a,从定义上:
类是一组数据集合(属性)和基于这个数据集合的一组操作(行为)类描述的是对象的共性特征,包括属性和行为
接口只是行为和常量属性的集合
b,从行为的关系上:
类中的行为都是有直接间接关系的,都可以访问同一个数据集合
接口中的行为,往往没啥关系
接口的注意事项
1,定义Java类的语法格式:先写extends,后写implements
class SubClass extends SuperClass implements InterfaceA{ }
2,一个类可以实现多个接口,接口也可以继承其它接口,这就是Java当中的“多继承”
3,实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类。
4,接口的主要用途就是被实现类实现
5,与继承关系类似,接口与实现类之间存在多态性
6,接口和类是并列关系
Java 8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
**静态方法:**使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行
其方法体。
**默认方法:**默认方法使用 default 关键字修饰。可以通过实现类对象来调用。
| 编号 | 区别点 | 抽象类 | 接口 |
|---|---|---|---|
| 1 | 定义 | 包含抽象方法的类 | 抽象方法和全局常量的集合 |
| 2 | 组成 | 构造方法、抽象方法、普通方法、常量、变量 | 常量、抽象方法、(jdk8:默认方法、静态方法) |
| 3 | 使用 | 子类继承抽象类(extends) | 子类实现接口(implements) |
| 4 | 关系 | 抽象类可以实现多个接口 | 接口不能继承抽象类,但允许继承多个接口 |
| 5 | 对象 | 不能创建对象,但是有构造方法 | 不能创建对象,也没有构造方法 |
| 6 | 局限 | 抽象类不能被多继承 | 接口之间能多继承,能被多实现 |
| 7 | 思想 | 作为模板或对共性抽象,is-a | 作为标准或对共性能力抽象,like-a |
| 8 | 选择 | 如果抽象类和接口都可以使用的话,优先使用接口,因为避免单继承的局限 |
接口就是这样的一种规范,它抽取了事物的相似行为,而不关心事物有什么关系
1,相比于继承抽象类的“is-a”关系,体现的是“是XX”思想,而实现接口体现的是“能够XX”的思想
2,接口允许多实现。实现多个接口,继承它们所有的属性和方法
3,接口的本质是契约、规范、标准
本文深入介绍了Java中抽象类和接口的相关知识。阐述了抽象类的概念、特点、成员特点及子类特点,还说明了abstract关键字的使用注意点。同时,引入接口概念,介绍其特点、成员特点、与类的关系及注意事项,指出接口是一种规范,体现‘能够XX’思想。

被折叠的 条评论
为什么被折叠?



