1.抽象类
1.1 抽象类的概述
(1)概述
在继承关系中,我们将子类中的共性功能向上抽取到父类,并且对这些共性功能在父类中给出了具体的实现。但是实际上父类并不知道子类对于共性功能的具体实现,所以可以将共性功能抽象出来,具体的实现细节由子类自身的差异性,去具体实现。
所以,父类只需要给出共性功能的声明即可,也就是把共性功能定义为抽象的。
(2)抽象类的特点
1.抽象类和抽象方法必须用abstract关键字修饰
抽象类格式: abstract class 类名 {}
抽象方法格式: public abstract void eat();
2.抽象类不一定有抽象方法,有抽象方法的类一定是抽象类。抽象类中的抽象方法,强制子类必须重写父类中所有的抽象方法。一旦一个类中有了抽象方法,此类必须为抽象类
3.抽象类中可以有构造方法,抽象类不能进行实例化,但是可以用于子类访问父类数据时的初始化。
4.抽象类不能直接实例化,那么按照多态的方式,由具体的子类实例化。
5.抽象类的子类
(1)要么是抽象类
(2)要么重写抽象类中的所有抽象方法
6.抽象类,不能直接创建对象
7.抽象类中的非抽象方法,一般作为子类继承使用,当然子类可以重写,但是不具备强制性。
public abstract class Person {
public String name;
public int age;
public abstract void eat();
public abstract void sleep();
}
public class Student extends Person {
@Override
public void eat() {
System.out.println("学生爱吃麻辣烫");
}
@Override
public void sleep() {
System.out.println("学生晚上狂欢,白天睡觉");
}
public void learn() {
System.out.println("学生爱学习");
}
}
public class Teacher extends Person {
@Override
public void eat() {
System.out.println("老师爱吃乾县哈水面");
}
@Override
public void sleep() {
System.out.println("老师晚上睡席梦思床");
}
public void teach() {
System.out.println("老师教书");
}
}
public class MyTest {
public static final int num = 100;
public static void main(String[] args) {
Person person = new Student();
person.name = "小花";
person.age = 18;
System.out.println(person.name);
System.out.println(person.age);
person.eat();
person.sleep();
Student student = (Student) person;//向下转型
student.learn();
System.out.println("=============================================================");
person = new Teacher();
person.name = "小明";
person.age = 36;
System.out.println(person.name);
System.out.println(person.age);
person.eat();
person.sleep();
Teacher t = (Teacher) person;
t.teach();
}
1.2抽象类的成员特点
(1)抽象类的成员特点:
成员变量:既可以是变量,也可以是常量。
构造方法:有,用于子类访问父类数据的初始化。
成员方法:既可以是抽象的,也可以是非抽象的。
(2)抽象类的成员方法特性:
抽象方法:强制要求子类做的事情。
非抽象方法:子类继承的事情,提高代码复用性。
1.3抽象类的知识
1.一个类中如果没有抽象方法,可不可以定义为抽象类?如果可以,有何意义?
抽象类中可以有抽象方法,可以有非抽象方法。非抽象方法可以继承让子类进行使用,抽象方法要求子类必须进行重写。
一个类中如果没有抽象方法,可以定义为抽象类。
如果一个类中没有抽象方法,那它定义为抽象类的意义就是不能创建这个类的对象。
2.abstract关键字不能与哪些关键字进行共存?
abstrct不能与fianl关键字进行共存:abstract强制子类重写方法,final修饰的方法不能被子类进行重写
abstract不能与private关键字进行共存:private修饰的方法无法继承,也无法进行重写
abstract不能与static关键字共存:静态方法不参与重写,abstract修饰的方法要求子类进行重写
2.接口
2.1接口的概述
(1)概述
我们知道java中只支持单继承,但如果我们想定义一些功能,想让一个子类都继承实现,显然没办法做到,所有Java提供了接口这个概念。这样我们就可以用一个子类去实现多个接口。我们可以理解为接口就是特殊的抽象类。
为了体现事物的扩展性,Java中就提供了接口去定义这些额外的功能,并不给出具体的是实现。将来哪些类需要需要继承这些功能,只需要实现接口就行。
(2)接口的特点
1.接口用关键字interface表示 格式: interface 接口名 {}
2.类实现接口用implements表示 格式: class 类名 implements 接口名 {}
3.接口不能实例化,按照多态的方式来实例化。
4.接口的子类
(1)可以是抽象类。但是意义不大。
(2)可以是具体类。要重写接口中的所有抽象方法。
public class MyTest {
public static void main(String[] args) {
//接口:把事物的一些额外扩展的功能,定义到接口中,哪些事物想要具备这些扩展功能,可以实现该接口,对扩展功能做以具体实现。
Dog dog = new Dog();
//父类 exends 子类
Animal an = dog;
an.eat();
//父接口 implements 子类
JumpInterface jumpInterface = dog;
jumpInterface.jump();
}
}
public abstract class Animal {
public abstract void eat();
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
public class Dog extends Animal implements JumpInterface {
@Override
public void jump() {
System.out.println("狗经过不断地练习,学会了跳高");
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
public interface JumpInterface {
public abstract void jump();
}
2.2接口成员的特点
接口中成员的特点:
(1)接口中不能创建对象,完成实例化。
(2)接口与类不同,接口没有构造方法。
(3)接口中的成员变量全部都是公共的静态常量,成员变量前有默认的public static final修饰符。
(4)接口中没有非抽象方法,全部都是抽象方法,方法前有默认修饰符public abstract的修饰符。(JDK1.8之后在接口中提供了用default修饰的方法,可以给出功能的具体实现,子类可以继承下去用。 JDK1.8之后在接口中也可以定义静态方法,直接使用接口名来调用)
2.3类、接口的关系
(1)类与类:继承关系,只能单继承,可以多层继承。
public class MyTest {
public static void main(String[] args) {
//多态:父类的引用指向子类的对象
Fu fu = new Zi();
//多态访问成员变量,编译看父类,运行看父类
System.out.println(fu.num);
fu.show();
//想要访问子类中特有的成员需要向下转型
Zi zi= (Zi) fu;
System.out.println(zi.num);
}
}
//父类
class Fu{
//父类的成员变量
int num=30;
public void show(){
System.out.println("父类的show方法");
}
}
//子类
class Zi extends Fu{
//子类的成员变量
int num=100;
//子类重写父类的成员方法
@Override
public void show() {
System.out.println("子类的成员方法");
}
}
(2)类与接口:实现关系,可以单实现,也可以多实现。并且还可以在继承一个类的同时实现多个接口。
/接口,接口中的方法都是抽象方法,
//方法前有public abstract的默认修饰符
interface A{
public abstract void a();
public abstract void aa();
}
interface B{
public abstract void b();
}
//类与接口之间的关系:类与接口的关系是实现关系
//也就是说一个类可以实现多个接口
class C implements A,B
{
@Override
public void aa() {
}
@Override
public void a() {
}
@Override
public void b() {
}
}
(3)接口与接口:继承关系,可以单继承,也可以多继承。
interface A{
public abstract void a();
}
interface B{
public abstract void b();
}
//接口与接口之间的关系:是继承的关系,并且可以多继承
interface C extends A,B{
public abstract void c();
}
3.抽象类和接口的区别
成员区别:
抽象类:
成员变量:可以变量,也可以常量
构造方法:有构造方法
成员方法:可以抽象,也可以非抽象
接口:
成员变量:只可以是常量
构造方法:没有构造方法
成员方法:只可以是抽象
关系区别:
类与类:继承,单继承
类与接口:实现,单实现,多实现
接口与接口:继承,单继承,多继承
设计理念区别:
抽象类中定义的是该继承体系的共性功能。
接口中定义的是该继承体系的扩展功能。