前言
Hello,大家好!很开心与你们在这里相遇,我是一个喜欢文字、喜欢有趣的灵魂、喜欢探索一切有趣事物的女孩,想与你们共同学习、探索关于IT的相关知识,希望我们可以一路陪伴~
1. 抽象
- 什么是抽象
父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了。我们把没有方法主体的方法称为抽象方法。
Java语法规定,包含抽象方法的类就是抽象类。
父类中的方法应该不是具体的,具体的实现应该由子类来具体实现;但是父类中的方法一定是具有共性方法。
- 什么是抽象方法
只有方法的声明,没有方法体{}的方法,就是抽象方法。
- 什么是抽象类
抽象方法所在的类必定是一个抽象类。
1.1 抽象类和抽象方法
抽象方法:
使用abstract关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。
- 定义格式
修饰符 abstract 返回值类型 方法名 (参数列表);
- 示例
public abstract void run();
抽象类:
如果一个类包含抽象方法,那么该类必须是抽象类。
- 定义格式
public abstract class 类名字 {
}
- 代码示例
public abstract class Animal {
public abstract void run();
}
1.2 抽象的使用
具体的子类继承抽象的父类必须重写父类所有的抽象方法
抽象的子类继承抽象的父类,不用再去重写父类的所有抽象方法,这种是没有意义。
- 代码示例:
/**
* @Desc: 抽象类中可以有抽象方法,也可以有非抽象方法
* 有抽象方法的类,这类一定是一个抽象类
*/
public abstract class Animal {
//抽象类有构造方法吗? 有
public Animal(){}
//抽象类可以实例化 不能
/**
* 抽象方法一定是共有,只不过每个子类实现的方式不一样
*/
public abstract void eat();
public abstract void run();
public void show(){
System.out.println("我是动物中show方法");
}
}
/**
* @Desc: 子类如果是一个具体的类,必须重写父类中所有抽象方法
*/
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void run() {
System.out.println("猫走猫步");
}
}
/**
* @Desc: 子类如果是抽象的,不需要重写父类中的抽象方法
*/
public abstract class Dog extends Animal {
}
/**
* @Desc: 如果子类继承抽象类,抽象类中有抽象方法必须要重写,有非抽象方法,直接继承
*/
public class CatTest {
public static void main(String[] args) {
//抽象类本身是不可以实例化
// Animal an = new Animal();
Cat c = new Cat();
//重写抽象类中的方法
c.eat();
c.run();
//直接继承过来的show方法
c.show();
}
}
【注意】此时的方法重写,是子类对父类抽象方法的完成实现,我们将这种方法重写的操作,也叫做实现方法。
1.3 抽象的注意事项
1、有抽象方法的类,这个类一定是抽象类
2、抽象类中可以有抽象方法,也可以有普通方法
3、抽象类有没有构造方法 有
4、抽象类是否可以实例化 不能
5、抽象类中的普通方法如何调用,通子类继承过来即可调用
- 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
- 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
- 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
- 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类 。
1.4 抽象类关键字使用
abstract不能和以下关键字一块使用
private 冲突
final 冲突
static 冲突
- 代码示例
public abstract class Fu {
//非法的修饰符组合
// private abstract void show();
//非法的修饰符组合
// final abstract void method();
//非法的修饰符组合
// static abstract void method();
//可以有静态方法
public static void method1(){
System.out.println("method1");
}
}
2. 接口
2.1 接口基本概述及格式
- 接口概述
USB接口:电脑上 有口,意味着只要一些设备 是支持USB接口方式,就可以连接(插)到USE接口上。
USB键盘、USB鼠标 USB U盘等等;都需要符合一个标准:USB标准。
JAVA里面的接口概念,也是一个标准,也是一个规范。 JAVA是面向接口的编程。项目经理、架构师,给程序员接口文档,你按照接口文档,写code即可。
接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法(功能),包含抽象方法 (JDK7及以前) , 默认方法和静态方法(JDK8)私有方法(JDK9)。
【总结】
接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用。
Java中的接口更多的体现在对行为的抽象!
应用场景:为了功能扩展,提高程序的可扩展性。
java不支持,多重继承,假设现在有一个需求,就需要继承多个类 的特点?变通方式,接口。
坦克:陆地跑 突突
船:游泳,滑行;
登录到岛屿的坦克:两栖坦克:
- 接口定义格式
接口用关键字interface修饰
public interface 接口名 {}
- 接口的使用
接口是不能创建对象,必须有实现类才能使用,类实现接口用implements表示
public class 类名 implements 接口名 {}
【注意】 接口的实现类必须重写接口中的所有的抽象方法,要么该类是一个抽象类
2.2 接口成员的特点
- 成员变量
只能是常量,默认修饰符:public static final
- 成员方法
只能是抽象方法,默认修饰符:public abstract
- 构造方法
没有,因为接口主要是扩展功能的,而没有具体存在
- 代码示例----接口
public interface Inter {
//接口只能是常量
//默认修饰符:public static final
public int num1 = 10;
public final int num2 = 20;
public static final int num3 = 30;
int num4 = 40;
//接口没有构造方法
// public Inter() {}
//接口中不能有方法主体
// public void show() {}
//默认修饰符:public abstract
public abstract void method1();
public void method2();
void show();
}
- 代码示例----实现类
//子类可以是抽象类。但是意义不大
public abstract class InterImpl extends Object implements Inter {}
/**
* 子类是具体类,要实现接口中所有的抽象方法
* 所有类都默认继承Object类,Object类是所有类的超类
*/
public class InterImpl extends Object implements Inter {
public InterImpl(){
super();//所有super走得是object类
}
@Override
public void method1() {
System.out.println("实现类中的method1");
}
@Override
public void method2() {
System.out.println("实现类中的method2");
}
@Override
public void show() {
System.out.println("实现类中的show");
}
}
- 代码示例----测试类
public class Test {
public static void main(String[] args) {
//接口不能实例化
// Inter i = new Inter();
//通过多态的方法实现 Fu f = new Zi();
Inter i = new InterImpl();
//访问成员变量
System.out.println(i.num1);
//接口的常量是不能修改的
// i.num1 = 100;
i.method1();
i.method2();
i.show();
}
}
2.3 接口默认方法的定义和使用
默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写。
- 默认方法定义格式
public default 返回值类型 方法的名称(参数列表){
方法体
}
- 默认方法的好处
接口的默认方法,实现类可以不用重写,默认方法可以用于接口升级
/**
* @Auther: yh
* @Desc 实现类没有没重写默认方法呢?
* 接口中的抽象方法是必须要重写(实现)
* 接口中的默认方法,不用重写,也可以手动重写,你默认方法存在的意义?
*
* 如果今后项目代码已以经写好,后期可能要扩展,接口中加新的方法(功能),如果你加抽象方法(功能)
* 所有的实现类有影响,所以针对以上后期可能要扩展功能的话,代码的维护性比较差,出现了默认方法
*/
- 定义接口
public interface LiveAble {
//接口的默认方法
public default void fly(){
System.out.println("天上飞");
}
}
- 定义实现类
public class LiveAbleImpl implements LiveAble {
// default 可以选择是否重写,也可以根据实际需求进行重写
/*
@Override
public void fly() {
System.out.println("自由自在的飞");
}
*/
}
- 定义测试类
public class InterfaceDemo {
public static void main(String[] args) {
// 创建子类对象
LiveAble a = new LiveAbleImpl();
// 调用默认方法
a.fly();
}
}
2.4 接口静态方法的定义和使用
静态方法:使用 static 修饰,供接口直接调用。
静态与.class文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用
- 静态方法定义格式
public static 返回值类型 方法名称(参数列表){
方法体
}
- 静态方法使用
1. 定义接口
public interface LiveAble {
//静态方法
public static void show2(){
System.out.println("静态方法-show2");
}
}
2. 定义实现类
public class LiveAbleImpl implements LiveAble {
// 无法重写静态方法
}
3. 定义测试类
public class InterfaceDemo {
public static void main(String[] args) {
//无法调用
// LiveAble l = new LiveAbleImpl();
// l.show2();
//接口名.静态方法(参数列表)
LiveAble.show2();
}
}
2.5 继承父类并实现多个接口
在继承体系中,一个类只能继承一个父类。而对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现。并且,一个类能继承一个父类,同时实现多个接口。
- 多实现格式
class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【不重名时可选】
}
- 代码示例
1. 定义接口
interface A {
public abstract void showA();
public abstract void show();
}
interface B {
public abstract void showB();
public abstract void show();
}
2. 定义父类
public class Fu{}
3. 定义实现类
public class C extends Fu implements A,B{
@Override
public void showA() {
System.out.println("showA"); }
@Override
public void showB() {
System.out.println("showB"); }
@Override
public void show() {
System.out.println("show"); }
}
【注意】
接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果实现类继承了父类,这个父类是一个抽象类时,我们还需要再重写抽象类中的所有抽象方法。
2.6 接口之间的多继承
- 定义多接口
interface A {
public void method1();
}
interface B {
public void method2();
}
- 定义子接口
interface C extends A,B{
public void method2();
}
//实现的方法有 C 和 A B 一共三个方法
class D implements C{}
【注意】
接口多继承之后,如果想使用,我们还必须定义实现类,才能使用。
2.7 类与类的关系
类与类:
继承关系,只能单继承(一个子类继承一个父类),不能多继承,可以多层次继承(子类C继承自类B,类B继承自 类A)。
接口与接口:
继承关系,可以单继承也可以多继承。public interface Sister extends Father,Mother
类与接口:
实现关系,可以单实现,也可以多实现。 public class Son extends Object implements Father,Mother
类和类及接口
并且还可以在继承一个类的同时实现多个接口。
2.8 抽象类和接口的区别
A:成员区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
抽象类不能实现化
成员方法:可以抽象,也可以非抽象
接口:
成员变量:只可以静态常量 可以省略 public static final
构造方法:无
接口不能实例化
成员方法:可以抽象 可以省略public abstract
有默认方法
静态方法
B:关系区别
类与类
继承,单继承, 多层继承
类与接口
实现,单实现,多实现
接口与接口
继承,单继承,多继承C:设计理念区别
抽象类【共性功能】。
接口【扩展功能】。
2.9 接口案例
- 需求
对猫和狗进行训练,他们可以跳高了,这里加入跳高功能。
请采用抽象类和接口来实现猫狗案例,并在测试类中进行测试。
- 代码实现
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();
}
接口Jumping:
public interface Jumping {
public abstract void jump();
}
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("猫可以跳高了");
}
}
测试类:
public class AnimalDemo {
public static void main(String[] args) {
Cat c = new Cat();
c.setName("加菲");
c.setAge(5);
System.out.println(c.getName()+","+c.getAge());
c.eat();
c.jump();
}
}
慢一点也没关系,只要是在变好的路上~ 希望你今天也开心呀~