五、抽象类

#抽象方法

抽象方法:将共性的行为(方法)抽取到父类之后。

由于每一个子类执行的内容是不一样

所以,在父类中不能确定具体的方法体

该方法就可以定义为抽象方法

抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类

#抽象类和抽象方法的定义格式

抽象方法的定义格式:

public abstract 返回值类型 方法名(参数列表);

抽象类的定义格式:

public abstract class 类名{}

#抽象类和抽象方法的意义

强制子类必须按照这种格式进行重写

#抽象类和抽象方法的注意事项

抽象类不能实例化

抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

可以有构造方法

抽象类的子类

要么重写抽象类中的所有抽象方法

要么是抽象类

练习、编写带有抽象类的标准Javabean类

青蛙frog 属性:名字,年龄 行为:吃虫子,喝水

狗Dog 属性:名字,年龄 行为:吃骨头,喝水

山羊Sheep 属性:名字,年龄 行为:吃草,喝水

Animal.Java

package cn.nwafu.abstractdemo2;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 void drink(){System.out.println("动物在喝水");}public abstract void eat();
}

frog.Java

package cn.nwafu.abstractdemo2;public class frog extends Animal{public frog() {}public frog(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("青蛙在吃虫子");}
}

Dog.Java

package cn.nwafu.abstractdemo2;public class Dog extends Animal{public Dog() {}public Dog(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("狗在吃骨头");}
}

Sheep.Java

package cn.nwafu.abstractdemo2;public class Sheep extends Animal{public Sheep() {}public Sheep(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("山羊在吃草");}
}

Test.Java

package cn.nwafu.abstractdemo2;import java.sql.SQLOutput;public class Test {public static void main(String[] args) {frog f = new frog("qingwa",2);System.out.println(f.getName()+","+f.getAge());f.drink();f.eat();Dog d = new Dog("taidi",1);System.out.println(d.getName()+","+d.getAge());d.drink();d.eat();Sheep s = new Sheep("shanyang",3);System.out.println(s.getName()+","+s.getAge());s.drink();s.eat();}
}

六、接口

#为什么有接口?

接口 :就是一种规则,是对行为的抽象

#接口的定义和使用

接口用关键字interface来定义

public interface 接口名{}

接口不能实例化

接口和类之间是实现关系,通过implements关键字表示

public class 类名 implements 接口名{}

接口的子类(实现类)

要么重写接口中的所有抽象方法

要么是抽象类

注意1:接口和类的实现关系,可以单实现,也可以多实现。

public class 类名 implements 接口名1,接口名2{}

注意2:实现类还可以在继承一个类的同时实现多个接口。

public class类名 extends 父类 implements 接口名1,接口名2{}

#接口中成员的特点

成员变量

只能是常量

默认修饰符:public static final

构造方法 没有

成员方法

只能是抽象方法

默认修饰符:public abstract

JDK7以前:接口中只能定义抽象方法。

JDK8的新特性:接口中可以定义有方法体的方法。

JDK9的新特性:接口中可以定义私有方法。

#接口和类之间的关系

1.类和类的关系

继承关系,只能单继承,不能多继承,但是可以多层继承

2.类和接口的关系

实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口

3.接口和接口的关系

继承关系,可以单继承,也可以多继承

练习、编写带有接口和抽象类的标准Javabean类

我们现在有乒乓球运动员和篮球运动员,乒乓球教练和篮球教练。

为了出国交流,跟乒乓球相关的人员都需要学习英语。

请用所有知识分析,在这个案例中,哪些是具体类,哪些是抽象类,哪些是接口?

乒乓球运动员:姓名,年龄,学打乒乓球,说英语

篮球运动员:姓名,年龄,学打篮球

乒乓球教练:姓名,年龄,教打乒乓球,说英语

篮球教练:姓名,年龄,教打篮球

思路一

思路二、

BasketballSporter.Java

package cn.nwafu.a01demo5;public class BasketballSporter extends Sporter{public BasketballSporter() {}public BasketballSporter(String name, int age) {super(name, age);}@Overridepublic void study() {System.out.println("篮球运动员在学习");}
}

BasketCoach.Java

package cn.nwafu.a01demo5;public class BasketCoach extends Coach{public BasketCoach() {}public BasketCoach(String name, int age) {super(name, age);}@Overridepublic void teach() {System.out.println("篮球教练在教学");}
}

Coach.Java

package cn.nwafu.a01demo5;public abstract class Coach extends Person{public Coach() {}public Coach(String name, int age) {super(name, age);}public abstract void teach();
}

English.Java

package cn.nwafu.a01demo5;public interface English {public abstract void speakEnglish();
}

Person.Java

package cn.nwafu.a01demo5;
//因为现在我不想让外界去直接创建人的对象
//因为直接创建顶层父类人的对象此时是没有意义的
//所以我就把他写为抽象的。
public abstract class Person {private String name;private int age;public Person() {}public Person(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;}
}

PingPangCoach.Java

package cn.nwafu.a01demo5;public class PingPangCoach extends Coach
implements English{public PingPangCoach() {}public PingPangCoach(String name, int age) {super(name, age);}@Overridepublic void teach() {System.out.println("乒乓球教练在教学");}@Overridepublic void speakEnglish() {System.out.println("乒乓球教练在说英语");}
}

PingPangSporter.Java

package cn.nwafu.a01demo5;public class PingPangSporter extends Sporter implements English{public PingPangSporter() {}public PingPangSporter(String name, int age) {super(name, age);}@Overridepublic void study() {System.out.println("乒乓球运动员在学习");}@Overridepublic void speakEnglish() {System.out.println("乒乓球运动员在说英语");}
}

Sporter.Java

package cn.nwafu.a01demo5;public abstract class Sporter extends Person{public Sporter() {}public Sporter(String name, int age) {super(name, age);}public abstract void study();}

Test.Java

package cn.nwafu.a01demo5;public class Test {public static void main(String[] args) {
//        练习、编写带有接口和抽象类的标准Javabean类
//        我们现在有乒乓球运动员和篮球运动员,乒乓球教练和篮球教练。
//        为了出国交流,跟乒乓球相关的人员都需要学习英语。
//        请用所有知识分析,在这个案例中,哪些是具体类,哪些是抽象类,哪些是接口?
//                乒乓球运动员:姓名,年龄,学打乒乓球,说英语
//        篮球运动员:姓名,年龄,学打篮球
//        乒乓球教练:姓名,年龄,教打乒乓球,说英语
//        篮球教练:姓名,年龄,教打篮球PingPangSporter pps = new PingPangSporter("xuxin",27);System.out.println(pps.getName()+","+pps.getAge());pps.study();pps.speakEnglish();}
}

#补充知识点

一、JDK8与JDK9新增的方法

●JDK7以前:接口中只能定义抽象方法。

●JDK8的新特性:接口中可以定义有方法体的方法。(默认、静态)

●JDK9的新特性:接口中可以定义私有方法。

私有方法分为两种:普通的私有方法,静态的私有方法

1、JDK8开始接口中新增的方法

a.允许在接口中定义默认方法,需要使用关键字default修饰

作用:解决接口升级的问题

接口中默认方法的定义格式:

格式: public default 返回值类型 方法名(参数列表){}

范例: public default void show(){ }

接口中默认方法的注意事项:

默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字

public可以省略,default不能省略

如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写

Test.Java

package cn.nwafu.a01demo6;public class Test {public static void main(String[] args) {
//接口中默认方法的定义格式:
//格式: public default 返回值类型 方法名(参数列表){}
//范例: public default void show(){ }
//接口中默认方法的注意事项:
//默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字
//public可以省略,default不能省略
//如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写InterImpl ii = new InterImpl();ii.method1();ii.show();}
}

InterA.Java

package cn.nwafu.a01demo6;public interface InterA {
//    接口中默认方法的定义格式:
//    格式: public default 返回值类型 方法名(参数列表){}
//    范例: public default void show(){ }
//    接口中默认方法的注意事项:
//    默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字
//    public可以省略,default不能省略
//    如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写public default void show(){System.out.println("InterA接口中的默认方法-----show");
}
public abstract void method1();
}

InterB.Java

package cn.nwafu.a01demo6;public interface InterB {public default void show(){System.out.println("InterB接口中的默认方法-----show");}
}

InterImpl.Java

package cn.nwafu.a01demo6;public class InterImpl implements InterA ,InterB{@Overridepublic void show() {System.out.println("重写接口中的show方法");}@Overridepublic void method1() {System.out.println("实现类重写的抽象方法");}
}

b.允许在接口中定义定义静态方法,需要用static修饰

接口中静态方法的定义格式:

格式: public static 返回值类型 方法名(参数列表){ }

范例: public static void show(){ }

接口中静态方法的注意事项:

●静态方法只能通过接口名调用,不能通过实现类名或者对象名调用

public可以省略,static不能省略

Test.Java

package cn.nwafu.a01demo7;public class Test {public static void main(String[] args) {
//  接口中静态方法的定义格式:
//格式: public static 返回值类型 方法名(参数列表){ }
//范例: public static void show(){ }
//接口中静态方法的注意事项:
//静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
//public可以省略,static不能省略//调用接口中的静态方法Inter.show();//调用实现类中的静态方法//注意:静态发方法不是重写,只是刚好方法名一样而已//子类把从父类继承下来的虚方法表里面的方法进行覆盖了,这才叫重写。InterImpl.show();}
}

InterImpl.Java

package cn.nwafu.a01demo7;public class InterImpl implements Inter{@Overridepublic void method() {System.out.println("InterImpl重写的抽象方法");}public static void show(){System.out.println("实现类中的静态方法");}
}

Inter.Java

package cn.nwafu.a01demo7;public interface Inter {public abstract void method();public static void show(){System.out.println("接口中的静态方法");}
}

2.JDK9新增的方法

私有方法分为两种:普通的私有方法,静态的私有方法

接口中私有方法的定义格式:

格式1: private返回值类型方法名(参数列表){}

范例1: private void show(){ }

格式2: private static返回值类型方法名(参数列表){ }

范例2: private static void method(){ }

InterA.Java

package cn.nwafu.a01demo8;public interface InterA {public default void show1(){System.out.println("show1开始执行了");//System.out.println("记录在运行过程中的各种细节,这里有100行代码");show3();}public static void show2(){System.out.println("show2开始执行了");//System.out.println("记录在运行过程中的各种细节,这里有100行代码");show4();}//普通的私有方法,给默认方法服务的//注意:删掉defaultprivate /* default */ void show3(){System.out.println("记录在运行过程中的各种细节,这里有100行代码");}//静态的的私有方法,给静态方法服务的private static void show4(){System.out.println("记录在运行过程中的各种细节,这里有100行代码");}
}

二、接口的应用

1.接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了。

2. 当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态。

三、适配器设计模式

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。

简单理解:设计模式就是各种套路。

适配器设计模式:解决接口与接口实现类之间的矛盾问题

1.当一个接口中抽象方法过多,但是我只要使用其中一部分的时候,就可以适配器设计模式

2.书写步骤:

编写中间类XXXAdapter,实现对应的接口对接口中的抽象方法进行空实现

让真正的实现类继承中间类,并重写需要用的方法。

为了避免其他类创建适配器类的对象,中间的适配器类用abstract进行修饰

Inter.Java

package cn.nwafu.a01demo9;public interface Inter {//需求,只想用method5()void menthod1();void menthod2();void menthod3();void menthod4();void menthod5();void menthod6();void menthod7();void menthod8();void menthod9();void menthod10();
}

InterAdapter.Java

package cn.nwafu.a01demo9;
//设置成abstract是为了不让外界创建对象,没有意义
public abstract class InterAdapter implements Inter{@Overridepublic void menthod1() {}@Overridepublic void menthod2() {}@Overridepublic void menthod3() {}@Overridepublic void menthod4() {}@Overridepublic void menthod5() {}@Overridepublic void menthod6() {}@Overridepublic void menthod7() {}@Overridepublic void menthod8() {}@Overridepublic void menthod9() {}@Overridepublic void menthod10() {}
}

InterImpl.Java

package cn.nwafu.a01demo9;public class InterImpl extends InterAdapter{
//我需要用到哪个方法,就重写哪个方法就可以了@Overridepublic void menthod5() {System.out.println("只用第五个方法");}}

七、内部类

#类的五大成员:

属性、方法、构造方法、代码块、内部类

#什么是内部类?

在一个类的里面,再定义一个类。

举例:在A类的内部定义B类,B类就被称为内部类

#为什么要学习内部类?

B类表示的事物是A类的一部分,且B单独存在没有意义。

#内部类的分类

成员内部类

静态内部类

局部内部类

匿名内部类

1.成员内部类

写在成员位置的,属于外部类的成员

*成员内部类的代码如何书写

成员内部类可以被一些修饰符所修饰,比如: private, 默认,protected, public, static等

在成员内部类里面,JDK16之前不能定义静态变量,JDK 16开始才可以定义静态变量。

*如何创建成员内部类的对象

方式一:

在外部类中编写方法,对外提供内部类的对象。

方式二:

直接创建格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;

范例: Outer.Inner oi = new Outer( ).new Inner( );

*成员内部类如何获取外部类的成员变量

练习、

Test.Java

package cn.nwafu.a01innerclassdemo3;public class Test {public static void main(String[] args) {
//创建内部类的对象并且调用show方法Outer.inner oi = new Outer().new inner();oi.show();}
}

Outer.Java

package cn.nwafu.a01innerclassdemo3;public class Outer {private int a = 10;class inner{private int a =20;public void show(){int a =30;// Other.this 获取了外部类对象的地址值(见笔记)System.out.println(Outer.this.a);//10System.out.println(this.a);//20System.out.println(a);//30}}
}

2.静态内部类

#什么是静态内部类?

一种特殊的成员内部类

静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象。

#创建静态内部类对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();

#调用非静态方法的格式:先创建对象,用对象调用

#调用静态方法的格式:外部类名.内部类名.方法名();

Outer.Java

package cn.nwafu.a01innerclassdemo4;import java.io.OutputStream;public class Outer {int a =10;static int b = 20;//内部静态类static class Inter{public void show1(){//System.out.println(a);报错!因为a为非静态System.out.println(b);Outer o =new Outer();System.out.println(o.a);//调用需要创建对象System.out.println("非静态类的方法被调用了");}public static void show2(){//System.out.println(a);报错!因为a为非静态System.out.println(b);System.out.println("静态类的方法被调用了");}}
}

Test.Java

package cn.nwafu.a01innerclassdemo4;public class Test {public static void main(String[] args) {
//注意事项://1.静态内部类也是成员内部类中的一种//2.静态内部类只能访问外部类中的静态变量和静态方法,//如果想要访问非静态的需要创建外部类的对象。//创建静态内部类对象的格式://外部类名.内部类名 对象名= new 外部类名.内部类名();//调用静态方法的格式:外部类名.内部类名.方法名();//创建静态内部类的对象//只要是静态的东西,都可以用类名点直接获取Outer.Inter oi = new Outer.Inter();oi.show1();//静态方法Outer.Inter.show2();}
}

3.局部内部类(了解)

1.将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量。

2.外界是无法直接使用,需要在方法内部创建对象并使用

3.该类可以直接访问外部类的成员,也可以访问方法内的局部变量。

4.匿名内部类(重要)

本质上是隐藏了名字的内部类,可以写在成员位置,也可局部位置

#格式:new 类名或者接口名(){

重写方法;

};

#格式的细节

包含了继承或实现,方法重写,创建对象。

整体就是一个类的子类对象或者接口的实现类对象

#使用场景

当方法的参数是接口或者类时,

以接口为例,可以传递这个接口的实现类对象,

如果实现类只要使用一次,就可以用匿名内部类简化代码。

Test.Java

package cn.nwafu.a01innerclassdemo6;public class Test {public static void main(String[] args) {
//匿名内部类(重要)
//本质上是隐藏了名字的内部类
//#格式:new 类名或者接口名(){
//    重写方法;
//};new Swim() {@Overridepublic void swim() {System.out.println("重写swim方法");}public void method() {System.out.println("method");}};method1(new Animal(){@Overridepublic void eat() {System.out.println("gouchigutou");}});//在测试类中调用下面的method方法?//以前的方式如何调用?//要自己写一个子类继承Animal类//再创建子类的对象,传递给method方法//        Dog d = new Dog();
//        method1(d);//如果Dog类我只要用一次,那么还需要单独定义一个类太麻烦了。}public static void method1(Animal d){// Animal a = 子类对象 多态d.eat();//编译看左边,运行看右边}}

Animal.Java

package cn.nwafu.a01innerclassdemo6;public abstract class Animal {public abstract void eat();
}

Dog.Java

package cn.nwafu.a01innerclassdemo6;public class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗吃骨头2");}
}

Test2.Java

package cn.nwafu.a01innerclassdemo6;public class Test2 {public static void main(String[] args) {//接口的实现类对象//接口多态Swim s = new Swim(){@Overridepublic void swim() {System.out.println("swim重写");}};s.swim();new Swim(){@Overridepublic void swim() {System.out.println("swim重写");}}.swim();//调用方法}
}

Swim.Java

package cn.nwafu.a01innerclassdemo6;public interface Swim {public abstract void swim();
}

最后结尾附上我的源码,BiYing/Java学习12 - 码云 - 开源中国 (gitee.com)感兴趣的可以看看哈!

第十二课 Java基础篇——面向对象进阶(三)相关推荐

  1. 第十二课 Java基础篇——面向对象进阶(一)

    一.Static static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量 静态变量是随着类的加载而加载的,优先于对象出现的 练习1.定义数组工具类 需求:在实际开发中,经常会遇到一 ...

  2. 第九课 Java基础篇——面向对象(综合案例)

    1.文字版格斗游戏 格斗游戏,每个游戏角色的姓名,血量,都不相同,在选定人物的时候(〈new对象的时候),这些信息就应该被确定下来. Role.Java package cn.nwafu;import ...

  3. Java基础篇--面向对象(Object Oriented)

    Java基础篇--面向对象(Object Oriented) 1. 面向对象概念 1.1 什么事面向对象 1.2 理解面向对象 1.3 面向对象的特点 1.4 面向对象开发设计特征 2. 类与对象 2 ...

  4. 【Java基础】面向对象(三)

    [Java基础]面向对象(三) 一.多态 概念 引用类型转换 二.Object类 概述 常用方法 三.抽象类 抽象类与抽象方法的定义 注意事项 四.接口 概述 接口定义 含有抽象方法 含有默认方法和静 ...

  5. Java基础篇——面向对象编程

    ​ ​ 活动地址:CSDN21天学习挑战赛 学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩:迟一天就多一天平庸的困扰.各位小伙伴,如果您: 想系统/深入学习某技术知识点- 一个人摸索学习很难坚持 ...

  6. 第七课 Java基础篇——阶段性综合练习

    案例一.卖飞机票 需求:机票价格按照淡季旺季.头等舱和经济舱收费.输入机票原价.月份和头等舱或经济舱. 按照如下规则计算机票价格:旺季(5-10月)头等舱9折,经济舱8.5折,淡季[11月到来年4月) ...

  7. 100天精通Java (基础篇) —面向对象编程1.0【Java分水岭】

    目录 一.类与对象 1.养猫问题 2.使用之前学的技术解决 3.之前技术解决的缺点分析 4.代码 5.对象[属性,行为] 6.类与对象的关系示意图 7.类与对象的区别和联系 8.对象在内存中存在形式( ...

  8. 小汤学编程之JAVA基础day08——面向对象(三):抽象类与接口

    一.抽象类 1.抽象类的由来      2.几点注意     3.语法规则 二.接口 1.定义方式      2.属性和方法 三.总结 一.抽象类 1.抽象类的由来 "用进废退", ...

  9. 《Java 后端面试经》Java 基础篇

    <Java 后端面试经>专栏文章索引: <Java 后端面试经>Java 基础篇 <Java 后端面试经>Java EE 篇 <Java 后端面试经>数 ...

  10. Java基础篇——类与子类

    1. 什么是类,什么是子类? 类:类是Java程序的基本要素,一个Java应用程序就是由若干个类所构成的.类是Java语言中最重要的"数据类型". 子类:由继承得到的类叫子类. 引 ...

最新文章

  1. 极客Web前端开发资源大荟萃#007
  2. GBDT--简单理解
  3. php rest api lumen,使用Lumen框架创建 REST API 实例教程
  4. JavaSE基础笔记
  5. 进阶12 多线程、等待唤醒机制、线程池
  6. beego框架开发投票网站(1) beego基础之运行逻辑
  7. 用一套键盘鼠标同时控制两台电脑
  8. linux下可执行文件无法执行问题定位排查
  9. 复制EXCEL单元格的值到SpreadJs单元格中,会多加一个可见的空格和一个不可见的0宽度空格的解决方法(ie11)
  10. 穿山甲广告。swift穿山甲广告40001报错
  11. 关于“wuauclt.exe”病毒的清理
  12. java判断生肖_Java写出生肖年判断
  13. java套娃_Java也有俄罗斯套娃,内部类剖析
  14. Rust的前景怎么样?值不值的学—Rust对比、特色和理念
  15. clickhouse 副本引擎
  16. 2022微信支付V3避坑指南-paySign签名
  17. 4.1 拦截电话号码
  18. pytorch模型保存与加载总结
  19. html输入框电话代码,电话号码输入框测试用例
  20. win7系统下比较好用的桌面日程安排提醒软件是什么?

热门文章

  1. 【PB】数据窗口的修改属性
  2. matlab分布鲁棒优化程序 是学习wasserstein 距离 分布鲁棒的好程序 文章是基于综合能源的分布鲁棒优化
  3. 永恒之蓝(勒索病毒)
  4. 吃什么食物对眼睛最好
  5. C++ 地图涂色问题 栈递归
  6. 个人书籍收藏及问题研究(!!! , 读书计划)
  7. 【电脑讲解】笔记本怎么连接宽带,拨号和无线网络连接方法
  8. JavaScript中0.1 + 0.2 等于多少
  9. RADIUS服务器介绍
  10. Python 与金融科技6|上证50的收盘价汇总