第十二课 Java基础篇——面向对象进阶(三)
五、抽象类
#抽象方法
抽象方法:将共性的行为(方法)抽取到父类之后。
由于每一个子类执行的内容是不一样
所以,在父类中不能确定具体的方法体
该方法就可以定义为抽象方法
抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类
#抽象类和抽象方法的定义格式
抽象方法的定义格式:
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基础篇——面向对象进阶(三)相关推荐
- 第十二课 Java基础篇——面向对象进阶(一)
一.Static static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量 静态变量是随着类的加载而加载的,优先于对象出现的 练习1.定义数组工具类 需求:在实际开发中,经常会遇到一 ...
- 第九课 Java基础篇——面向对象(综合案例)
1.文字版格斗游戏 格斗游戏,每个游戏角色的姓名,血量,都不相同,在选定人物的时候(〈new对象的时候),这些信息就应该被确定下来. Role.Java package cn.nwafu;import ...
- Java基础篇--面向对象(Object Oriented)
Java基础篇--面向对象(Object Oriented) 1. 面向对象概念 1.1 什么事面向对象 1.2 理解面向对象 1.3 面向对象的特点 1.4 面向对象开发设计特征 2. 类与对象 2 ...
- 【Java基础】面向对象(三)
[Java基础]面向对象(三) 一.多态 概念 引用类型转换 二.Object类 概述 常用方法 三.抽象类 抽象类与抽象方法的定义 注意事项 四.接口 概述 接口定义 含有抽象方法 含有默认方法和静 ...
- Java基础篇——面向对象编程
活动地址:CSDN21天学习挑战赛 学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩:迟一天就多一天平庸的困扰.各位小伙伴,如果您: 想系统/深入学习某技术知识点- 一个人摸索学习很难坚持 ...
- 第七课 Java基础篇——阶段性综合练习
案例一.卖飞机票 需求:机票价格按照淡季旺季.头等舱和经济舱收费.输入机票原价.月份和头等舱或经济舱. 按照如下规则计算机票价格:旺季(5-10月)头等舱9折,经济舱8.5折,淡季[11月到来年4月) ...
- 100天精通Java (基础篇) —面向对象编程1.0【Java分水岭】
目录 一.类与对象 1.养猫问题 2.使用之前学的技术解决 3.之前技术解决的缺点分析 4.代码 5.对象[属性,行为] 6.类与对象的关系示意图 7.类与对象的区别和联系 8.对象在内存中存在形式( ...
- 小汤学编程之JAVA基础day08——面向对象(三):抽象类与接口
一.抽象类 1.抽象类的由来 2.几点注意 3.语法规则 二.接口 1.定义方式 2.属性和方法 三.总结 一.抽象类 1.抽象类的由来 "用进废退", ...
- 《Java 后端面试经》Java 基础篇
<Java 后端面试经>专栏文章索引: <Java 后端面试经>Java 基础篇 <Java 后端面试经>Java EE 篇 <Java 后端面试经>数 ...
- Java基础篇——类与子类
1. 什么是类,什么是子类? 类:类是Java程序的基本要素,一个Java应用程序就是由若干个类所构成的.类是Java语言中最重要的"数据类型". 子类:由继承得到的类叫子类. 引 ...
最新文章
- 极客Web前端开发资源大荟萃#007
- GBDT--简单理解
- php rest api lumen,使用Lumen框架创建 REST API 实例教程
- JavaSE基础笔记
- 进阶12 多线程、等待唤醒机制、线程池
- beego框架开发投票网站(1) beego基础之运行逻辑
- 用一套键盘鼠标同时控制两台电脑
- linux下可执行文件无法执行问题定位排查
- 复制EXCEL单元格的值到SpreadJs单元格中,会多加一个可见的空格和一个不可见的0宽度空格的解决方法(ie11)
- 穿山甲广告。swift穿山甲广告40001报错
- 关于“wuauclt.exe”病毒的清理
- java判断生肖_Java写出生肖年判断
- java套娃_Java也有俄罗斯套娃,内部类剖析
- Rust的前景怎么样?值不值的学—Rust对比、特色和理念
- clickhouse 副本引擎
- 2022微信支付V3避坑指南-paySign签名
- 4.1 拦截电话号码
- pytorch模型保存与加载总结
- html输入框电话代码,电话号码输入框测试用例
- win7系统下比较好用的桌面日程安排提醒软件是什么?