1 抽象类
1.1 概念
Java中父类可以定义没有方法体的方法,该方法由其子类来具体的实现。
该没有方法体的方法我们称之为抽象方法,含有抽象方法的类我们称之为抽象类。
抽象类可以理解为是一个只有方法声明没有方法体的特殊类。
举例:水果,东西。。
修饰符 abstract 返回值 方法名(参数列表);
1.2 特点
- 通过java关键字abstract实现
- 可以修饰方法或者类
- 抽象类中可以没有抽象方法(由子类去实现)/不让外界直接new
- 如果类中有抽象方法,那该类必须定义为一个抽象类
- 子类继承了抽象类以后,要么还是一个抽象类,要么就把所有抽象方法都重写
- 多用于多态中
- 抽象类不可以被实例化
1.3 入门案例
创建day08工程
创建cn.tedu.abstractdemo包
创建Test1_Abstract.java
package cn.tedu.abstractdemo;
//这个类用来测试抽象类的入门案例
public class Test1_Abstract {
public static void main(String[] args) {
//TODO 创建父类对象测试
//4、抽象类不可被实例化,不能new
// Animal a = new Animal(); a.eat(); //吃啥都行
//TODO 创建多态对象测试
Animal a2 = new Cat(); a2.eat(); //猫吃鱼
}
}
//创建抽象类
//3、如果类中包含抽象方法,这个类,必须是 抽象类
abstract class Animal{
//1、抽象方法 -- 没有方法体的方法
//2、使用abstract关键来描述抽象的
abstract public void eat() ;
//6、抽象类中也可以包含普通方法sleep()
// public void sleep() { System.out.println(1); }
abstract public void sleep();
}
//创建子类
//5、子类继承抽象类后:仍然是抽象类+重写所有抽象方法
//abstract class Cat extends Animal{
class Cat extends Animal{
//7、重写抽象类中的所有抽象方法,否则子类就是抽象类
@Override //@Override注解:重写的标志
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("正在睡觉");
}
}
2 抽象类的用法
2.1 构造方法
常用于子类的实例化
package cn.tedu.abstractdemo;
//这个类用来测试抽象类的用法
public class Test2_Abstract2 {
public static void main(String[] args) {
//TODO 创建多态对象测试
Human h = new Student();
}
}
//创建抽象父类
abstract class Human{
//1、抽象类中可以有构造方法,自己不能创建对象!用来给子类创建对象
public Human() {
System.out.println("Human()...");
}
}
//创建子类
class Student extends Human{
//TODO 构造方法
public Student() {
super();//默认就存在
System.out.println("Student()...");
}
}
2.2 成员变量
既可以有变量,也可以有常量。
package cn.tedu.abstractdemo;
//这个类用来测试抽象类的用法
public class Test2_Abstract2 {
public static void main(String[] args) {
//TODO 创建多态对象测试
Human h = new Student();
System.out.println(h.sum);//10
}
}
//创建抽象父类
abstract class Human{
//2、抽象类中可以有变量也可以有常量
int count = 10;
final int sum = 10; //final修饰的变量值不能变,是常量
//1、抽象类中可以有构造方法,用来给子类创建对象
public Human() {
System.out.println("Human()...");
}
}
//创建子类
class Student extends Human{
//TODO 构造方法
public Student() {
super();//默认就存在
System.out.println("Student()...");
}
}
2.3 成员方法
抽象类里,既可以有普通方法,有可以有抽象方法。
package cn.tedu.abstractdemo;
//这个类用来测试抽象类的用法
public class Test2_Abstract2 {
public static void main(String[] args) {
//TODO 创建多态对象测试
Human h = new Student();
System.out.println(h.sum);//10
}
}
//创建抽象父类
//5、如果类中,都是普通资源,这个类还是被设计成了抽象类 -- 目的就是不让外界创建对象
abstract class Human{
//2、抽象类中可以有变量也可以有常量
int count = 10;
final int sum = 10; //final修饰的变量值不能变,是常量
//1、抽象类中可以有构造方法,用来给子类创建对象
public Human() {
System.out.println("Human()...");
}
//3、抽象类中的成员方法可以有普通方法也可以有抽象方法
//TODO 普通方法
public void eat() {
System.out.println("吃啥都行");
}
//TODO 抽象方法
abstract public void game();
}
//创建子类
class Student extends Human{
//方法重写:
//abstract public void game();
public void game() {
System.out.println("吃鸡");
}
//TODO 构造方法
public Student() {
super();//默认就存在
System.out.println("Student()...");
}
}
3 接口
3.1 概念
Java里面由于不允许多重继承,所以如果要实现多个类的功能,则可以通过实现多个接口来实现。
Java接口和Java抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现。
<mark>OOP(Object Oriented Programming</mark>面向对象的编程,如果要提高程序的复用率,<mark>增加程序的可维护性,可扩展性</mark>,就必须是面向接口的编程,面向抽象的编程。
正确地使用接口、抽象类这些太有用的抽象类型做为java结构层次上的顶层。
interface 接口名{ 代码… }
3.2 特点
- 接口中都是<mark>抽象方法</mark>
- 通过interface关键字创建接口
- 通过implements让子类来实现
- 可以理解成,接口是一个特殊的抽象类
- 接口突破了java的单继承的局限性
- 接口和类之间可以多实现,接口和接口之间可以多继承
- <mark>接口是对外暴露的规则,是一套开发规范</mark>
- <mark>接口提高了程序的功能扩展,降低了耦合性</mark>
3.3 入门案例
接口:
package cn.tedu.interfacedemo;
//这个类用来测试接口的入门案例
//1、通过interface关键字定义接口
public interface Test3_Inter {
//2、接口里都是抽象方法
abstract public void eat();
abstract public void sleep();
}
接口的实现类:
package cn.tedu.interfacedemo;
//这个类作为接口的实现类
//1、子类用implements关键字实现接口
//2、子类实现接口后,可以是一个抽象子类
//abstract public class InterImpl implements Test3_Inter{
public class InterImpl implements Test3_Inter{
//2.1、子类实现接口后,也可以把所有抽象方法都重写
@Override
public void eat() {
System.out.println("正在吃饭");
}
@Override
public void sleep() {
System.out.println("正在睡觉");
}
}
测试类:
package cn.tedu.interfacedemo;
//这个类用来测试接口的使用
public class Test4_InterImpl {
public static void main(String[] args) {
//TODO 创建多态对象测试
Test3_Inter in = new InterImpl();
in.eat();
in.sleep();
}
}
3.4 入门案例2
package cn.tedu.interfacedemo;
//这个类用来测试接口的多继承多实现
public class Test5_Inter2 {
public static void main(String[] args) {
//TODO 创建多态对象测试
Inter2 i2 = new Inter2Impl();
i2.eat();
i2.study();
}
}
//创建接口
//1、通过interface创建接口
interface Inter2{
//2、接口里都是抽象方法
abstract public void eat();
abstract public void study();
}
interface Inter3{
//2、接口里都是抽象方法
abstract public void sleep();
abstract public void game();
}
// ii)接口和接口之间是继承关系,而且可以多继承,这时Inter4接口的功能最多
interface Inter4 extends Inter2,Inter3{
//2、接口里都是抽象方法
abstract public void play();
abstract public void run();
}
//创建子类使用接口里的功能
//3、通过implements关键字发生子类和接口间的实现关系
//i)子类和接口之间是实现关系,子类可以同时拥有多个接口的功能,还可以多实现
//这时实现类需要重写所有接口的所有抽象方法
class Inter2Impl implements Inter2,Inter3{
//4、子类实现接口后,可以是抽象子类,也可以重写所有抽象方法
@Override
public void eat() {
System.out.println("正在吃饭");
}
@Override
public void study() {
System.out.println("正在学习");
}
public void sleep() {
System.out.println("正在睡觉");
}
public void game() {
System.out.println("正在玩游戏");
}
}
4 接口的用法
4.1 构造方法
<mark>接口里是没有构造方法的。</mark>
在创建实现类的对象时默认的super(),是调用的默认Object的无参构造。
package cn.tedu.interfacedemo;
//这个类用来测试接口的用法
public class Test6_UseInter {
public static void main(String[] args) {
}
}
//创建接口
interface Fu{
//1、接口里没有构造方法
//public Fu() { }
}
4.2 成员变量
接口里没有成员变量,都是常量。所以,<mark>你定义一个变量没有写修饰符时,默认会加上:</mark>
<mark>public static final</mark>
package cn.tedu.interfacedemo;
//这个类用来测试接口的用法
public class Test6_UseInter {
public static void main(String[] args) {
//TODO 创建多态对象测试
Fu f = new FuImpl();
// f.sum=20; 常量,值不能被修改
System.out.println(f.sum);
System.out.println(Fu.sum);//sum是static的
}
}
//创建接口
interface Fu{
//1、接口里没有构造方法
//public Fu() { }
//2、接口里没有变量,都是静态常量:会自动为变量拼接public static final
//public static final int sum = 10;
int sum = 10;
}
//创建实现类
class FuImpl implements Fu{
}
4.3 成员方法
<mark>接口里的方法,默认就都是抽象的,如果你不写明是abstract的,那会自动补齐。</mark>
<mark>例如:abstract void save</mark>
package cn.tedu.interfacedemo;
//这个类用来测试接口的用法
public class Test6_UseInter {
public static void main(String[] args) {
//TODO 创建多态对象测试
Fu f = new FuImpl();
// f.sum=20;
System.out.println(f.sum);
System.out.println(Fu.sum);//sum是static?
}
}
//创建接口
interface Fu{
//1、接口里没有构造方法
//public Fu() { }
//2、接口里没有变量,都是静态常量:会自动为变量拼接public static final
//public static final int sum = 10;
int sum = 10;
//3、接口里都是抽象方***自动拼接public abstract
//public abstract void eat();
void eat() ;
}
//创建实现类
class FuImpl implements Fu{
//3.1、接口里有抽象方法,实现类必须重写
@Override
public void eat() {
System.out.println("。。。");
}
}
4.4 总结
1、类和类的关系
-- 继承关系extends,只支持单继承
-- class A extends B
-- 其中,A是子类 B是父类
-- 方法的重写!!
2、类和接口的关系
-- 实现关系implments,还可以多实现
-- class A implments B,C
-- 其中,A是子类 B C是接口
-- A 必须重写B C 接口里的所有抽象方法,否则A是抽象类
3、接口和接口的关系
-- 继承关系,还可以多继承
-- interface A extends B,C
-- 其中A B C 都是接口,A接口的功能最全
-- class X implments A
-- 其中X子类需要重写A B C 里的所有抽象方法
4、抽象类和接口的区别
-- 抽象类是一个特殊的类,特殊在抽象类里可以有抽象方法
-- 接口是一个特殊的抽象类,特殊在接口里都是抽象方法
-- 细节见笔记7.2
5、继承的同时多实现
interface Fu{
}
interface Fu2{
}
class Animal{
}
//创建实现类
//继承的同时多实现
class FuImpl extends Animal implements Fu,Fu2{
5 设计模式
软件设计模式(Design pattern),又称设计模式,
是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
1995 年,GoF(Gang of Four,四人组/四人帮)合作出版了《设计模式:可复用面向对象软件的基础》一书,共收录了 23 种设计模式,从此树立了软件设计模式领域的里程碑,人称「GoF设计模式」。
这 23 种设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性,以及类的关联关系和组合关系的充分理解。
当然,软件设计模式只是一个引导,在实际的软件开发中,必须根据具体的需求来选择:
- 对于简单的程序,可能写一个简单的算法要比引入某种设计模式更加容易
• 但是对于大型项目开发或者框架设计,用设计模式来组织代码显然更好
5.1 单例设计模式概念
单例模式可以说是大多数开发人员在实际中使用最多的,常见的。
Spring默认创建的bean就是单例模式的。
单例模式有很多好处,比如可节约系统内存空间,控制资源的使用。
其中单例模式最重要的是确保对象只有一个。
简单来说,保证一个类在内存中的对象就一个。
RunTime就是典型的单例设计,我们通过对RunTime类的分析,一窥究竟。
5.2 源码分析
<Runtime源码分析 - 单例设计模式>
https://blog.csdn.net/LawssssCat/article/details/103012982
6 [作业]分析老师示例
具体事物:培优班老师CgbTeacher 高手班老师ActTeacher
共性:讲课 备课
测试:创建多态对象测
面向抽象编程:
面向接口编程:
7 扩展
<mark>7.1 abstract注意事项</mark>
抽象方法要求子类继承后必须重写。那么,abstract关键字不可以和哪些关键字一起使用呢?以下关键字,在抽象类中。用是可以用的,只是没有意义了。
- private:被私有化后,子类无法重写,与abstract相违背。
- static:静态的,优先于对象存在。而abstract是对象间的关系,存在加载顺序问题。
- final:被final修饰后,无法重写,与abstract相违背。
7.2 接口和抽象类的区别
- 抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
- 抽象类要被子类继承,接口要被类实现。
- 接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
- 接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
- 抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
- 抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
- 抽象类里可以没有抽象方法
- 如果一个类里有抽象方法,那么这个类只能是抽象类
- 抽象方法要被实现,所以不能是静态的,也不能是私有的。
- 接口可继承接口,并可多继承接口,但类只能单根继承。