抽象:是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征的过程。具体地说,抽象就是人们在实践的基础上,对于丰富的感性材料通过去粗取精、去伪存真、由此及彼、由表及里的加工制作,形成概念思维形式,以反映事物的本质和规律的方法。
其实说白了,抽象就是把事物的共同特征总结为一点。 他和具体又是相对的。就比如说“男人”对于“人类”是具体的,而“动物”对于“人类”又是抽象的。抽象—》抽出相同特征的对象,他也有个同义词叫归类。
抽象类:抽象方法所在的类,必须是抽象类,在class前加一个abstract关键字
抽象方法:加上abstract关键字,然后去掉大括号,直接分号结束
/**
* 抽象类:抽象方法所在的类,必须是抽象类,在class前加一个abstract关键字
* 抽象方法:加上abstract关键字,然后去掉大括号,直接分号结束
*/
public abstract class Animal {
//这是一个抽象方法,代表吃东西,但是具体吃什么,大括号中的内容不确定
public abstract void eat();
//这是一个普通的成员方法
public void method(){
}
}
/**
* 抽象类:抽象方法所在的类,必须是抽象类,在class前加一个abstract关键字
* 抽象方法:加上abstract关键字,然后去掉大括号,直接分号结束
* 使用步骤:
* 1、不能直接new抽象类的对象
* 2、必须用子类继承抽象父类
* 3、子类必须覆盖重写父类当中所有的抽象方法,即重写时去掉abstract关键字,补充上方法体大括号
* 4、创建子类对象进行使用
*/
public abstract class Animal {
//这是一个抽象方法,代表吃东西,但是具体吃什么,大括号中的内容不确定
public abstract void eat();
//这是一个普通的成员方法
public void method(){
}
}
public class Cat extends Animal{
//重写父类的抽象方法
@Override
public void eat() {
System.out.println("猫吃老鼠");
}
/**
* 测试抽象类
*/
public class TestAbstract {
public static void main(String[] args) {
//创建实现类对象
Cat cat = new Cat();
//调用方法
cat.eat();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BZsHUHnx-1686205722653)(photo/JavaSE09_抽象类和接口.assest/1664812707347.png)]
1、抽象类不能创建对象,如果创建编译错误,只能创建抽象类的非抽象子类的对象
2、抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的
子类的构造方法中,有默认的super(),需要访问父类的构造方法
3、抽象类中,不一定包含抽象方法,但是有抽象方法的类一定是抽象类
4、抽象类的子类,必须重写抽象父类中的抽象方法,否则,编译错误,除非该子类也是抽象类
接口:就是一种公共的规范标准,只要符合规范标准,就可以调用。
比如电脑的USB口就是一种规范,符合规范的标准的前提下,鼠标,键盘,U盘等都可以调用
接口:是多个类的公共规范,接口是一种引用数据类型
格式:
public interface 接口名称{
//接口内容
}
接口中可以包含的内容:
接口使用的三步骤
public class 实现类名称 impletements 接口名 {
//实现类的内容
}
/**
* 1、定义抽象方法
* 格式:public abstract 返回值类型 方法名(参数列表)
* 注意事项:
* 1、接口中的抽象方法,修饰符必须是两个固定的关键字:public abstract
* 2、这两个关键字修饰符,可以选择性的省略,省略任意一个或者全省都可以
*/
public interface InterfaceAbstract {
public abstract int method1();
public void method2();
abstract String method3();
int method4();
}
/**
* 2、实现类
*/
public class InterfaceAbstractImpl implements InterfaceAbstract{
@Override
public int method1() {
System.out.println("第1个抽象方法");
return 0;
}
@Override
public void method2() {
System.out.println("第2个抽象方法");
}
@Override
public String method3() {
System.out.println("第3个抽象方法");
return null;
}
@Override
public int method4() {
System.out.println("第4个抽象方法");
return 0;
}
}
/**
* 3、测试
*/
public class TestInterfaceAbstract {
public static void main(String[] args) {
//创建实现类对象
InterfaceAbstractImpl impl1 = new InterfaceAbstractImpl();
//调用方法
impl1.method1();
impl1.method2();
impl1.method3();
impl1.method4();
}
}
public default 返回值类型 方法名称(参数列表){
//方法体
}
/**
* 1、接口中默认方法(从java8开始)
* 格式:
* public default 返回值类型 方法名称(参数列表){
* //方法体
* }
* 注意事项:
* 1、public可以缺省不写,但是default必须写
* 2、接口中的默认方法可以解决接口升级的问题
*/
public interface InterfaceDefault {
//1、抽象方法
public abstract int method1();
//2、在此接口的实现类已经投入使用的情况下,需要升级接口,
// 按照惯性思维,需要添加一个抽象方法,实现类也需重新实现,不切实际
//public abstract void method2();
//3、新添加的方法,使用默认方法形式,实现接口升级,同时已投入使用的实现类可以直接使用
public default void methodDefault(){
System.out.println("我是新添加的默认方法");
}
}
/**
* 2、实现类A
*/
public class InterfaceDefaultImplA implements InterfaceDefault{
@Override
public int method1() {
System.out.println("第一个抽象方法的实现");
return 0;
}
}
/**
* 实现类B
*/
public class InterfaceDefaultImplB implements InterfaceDefault{
@Override
public int method1() {
System.out.println("第一个抽象方法的实现");
return 0;
}
@Override
public void methodDefault() {
System.out.println("我是新添加的默认方法被重写");
}
}
/**
* 4、测试
*/
public class TestDefault {
public static void main(String[] args) {
//创建接口实现类对象
InterfaceDefaultImplA implA = new InterfaceDefaultImplA();
//调用方法
implA.method1();
//调用接口新增的默认方法,如果实现类中没有,则会向上找接口
implA.methodDefault();
System.out.println("----------------");
InterfaceDefaultImplB implB = new InterfaceDefaultImplB();
//调用方法
implB.method1();
//调用重写的默认方法
implB.methodDefault();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jgbIBKeB-1686205722654)(photo/JavaSE09_抽象类和接口.assest/1664873584907.png)]
接口中定义静态方法(从java8开始)
public static 返回值类型 方法名(){
//方法体
}
注意事项
/**
* 1、接口中定义静态方法(从java8开始)
* 格式:
* public static 返回值类型 方法名(){
* //方法体
* }
* 注意事项:
* 1、方法上右static关键字修饰
* 2、静态方法有方法体
* 3。public可以省略
* 4、不能使用接口的实现类来调用接口中的静态方法
*/
public interface InterfaceStatic {
//接口中定义静态方法
public static void methodStatic(){
System.out.println("我是接口中的静态方法");
}
}
/**
* 2、实现类
*/
public class InterfaceStaticImpl implements InterfaceStatic{
}
/**
* 3、测试
*/
public class TestStatic {
public static void main(String[] args) {
//创建实现类对象
InterfaceStatic impl = new InterfaceStaticImpl();
//不能使用接口实现类对象直接调用接口中的静态方法
//impl.methodStatic();
//需要使用接口名.静态方法名,进行直接调用
InterfaceStatic.methodStatic();
}
}
/**
* 接口中定义私有方法(从java9开始)
* 1、普通私有方法:解决多个默认方法之间重复代码问题,重复代码提取到普通私有方法中
* 格式:private 返回值类型 方法名称(参数列表){方法体}
* 2、静态私有方法:解决多个静态方法之间重复代码问题,重复代码提取到静态私有方法中
* 格式:private static 返回值类型 方法名称(参数列表){方法体}
*/
public interface InterfacePrivateA {
public default void methodDefaultA(){
System.out.println("默认方法A");
methodAB();
}
public default void methodDefaultB(){
System.out.println("默认方法B");
methodAB();
}
//共性的内容存放在私有方法中
private void methodAB(){
System.out.println("私有普通AAAA");
System.out.println("私有普通BBBB");
}
}
/**
* 接口中定义私有方法(从java9开始)
* 1、普通私有方法:解决多个默认方法之间重复代码问题,重复代码提取到普通私有方法中
* 格式:private 返回值类型 方法名称(参数列表){方法体}
* 2、静态私有方法:解决多个静态方法之间重复代码问题,重复代码提取到静态私有方法中
* 格式:private static 返回值类型 方法名称(参数列表){方法体}
*/
public interface InterfacePrivateB {
public static void methodDefaultA(){
System.out.println("静态方法A");
methodAB();
}
public static void methodDefaultB(){
System.out.println("静态方法B");
methodAB();
}
//共性的内容存放在私有静态方法中
private static void methodAB(){
System.out.println("私有静态AAAA");
System.out.println("私有静态BBBB");
}
}
/**
* 实现类A
*/
public class InterfacePrivateAImpl implements InterfacePrivateA{
}
/**
* 实现类B
*/
public class InterfacePrivateBImpl implements InterfacePrivateB{
}
/**
* 测试类
*/
public class TestPrivate {
public static void main(String[] args) {
//创建A类接口的实现类对象
InterfacePrivateAImpl implA = new InterfacePrivateAImpl();
//调用方法
implA.methodDefaultA();
implA.methodDefaultB();
System.out.println("-----------------");
//接口B名称直接调用静态方法
InterfacePrivateB.methodDefaultA();
InterfacePrivateB.methodDefaultB();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3bGQVvs6-1686205722654)(photo/JavaSE09_抽象类和接口.assest/1664878113371.png)]
接口中可以定义“成员变量”,也就是常量
这个成员变量必须使用public static final 三个关键字进行修饰,这其实就是接口中的常量
格式: public static final 数据类型 常量名称 = 常量值;
注意事项:
1、一旦使用final关键字修饰,就不可以改变
2、接口中的常量必须赋值
3、接口中常量的名称必须使用全部大写
4、接口中的变量总是需要定义为“ public static final 变量类型 变量名 = 变量值;”,
但可以不包含这些修饰符,编译器默认会添加这些限制
因为接口是不可能有直接实例的,那样的话也就不可能修改(final),
同样也不可能通过实例访问的(static)
public class InterfaceConst {
//这其实就是一个常量,一旦赋值,不可以修改
public static final int NUM = 100;
//常量的修饰符可以缺省
int NUM2 = 200;
}
/**
* 测试:访问接口中的常量
*/
public class TestConst {
public static void main(String[] args) {
//使用接口名.常量名访问
System.out.println(InterfaceConst.NUM);
}
}
在Java9版本中,接口的内容可以有:
接口的使用注意事项:
public interface InterfaceA {
public abstract void methodA();
//接口之间抽象方法重名
public abstract void methodSame();
//接口之间默认方法重名
public default void methodDefault(){
System.out.println("默认方法AAA");
}
}
public interface InterfaceB {
public abstract void methodB();
//接口之间抽象方法重名
public abstract void methodSame();
//接口之间默认方法重名
public default void methodDefault(){
System.out.println("默认方法BBB");
}
}
public class InterfaceImpl implements InterfaceA,InterfaceB{
@Override
public void methodA() {
System.out.println("重写了接口A的抽象方法");
}
@Override
public void methodB() {
System.out.println("重写了接口B的抽象方法");
}
@Override
public void methodSame() {
System.out.println("重写AB接口中都有的重名抽象方法,只写一个即可");
}
@Override
public void methodDefault() {
System.out.println("实现类必须重写接口中重名冲突的默认方法,只写一个即可");
}
}
public class TestInterfaceAB {
public static void main(String[] args) {
InterfaceImpl impl = new InterfaceImpl();
impl.methodA();
impl.methodB();
impl.methodSame();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pgKIfXMU-1686205722655)(photo/JavaSE09_抽象类和接口.assest/1664883841425.png)]
接口与类的关系: