1 抽象类

1.1 概念

Java中父类可以定义没有方法体的方法,该方法由其子类来具体的实现。
该没有方法体的方法我们称之为抽象方法,含有抽象方法的类我们称之为抽象类。
抽象类可以理解为是一个只有方法声明没有方法体的特殊类。
举例:水果,东西。。

修饰符 abstract 返回值 方法名(参数列表);

1.2 特点

  1. 通过java关键字abstract实现
  2. 可以修饰方法或者类
  3. 抽象类中可以没有抽象方法(由子类去实现)/不让外界直接new
  4. 如果类中有抽象方法,那该类必须定义为一个抽象类
  5. 子类继承了抽象类以后,要么还是一个抽象类,要么就把所有抽象方法都重写
  6. 多用于多态中
  7. 抽象类不可以被实例化

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 特点

  1. 接口中都是<mark>抽象方法</mark>
  2. 通过interface关键字创建接口
  3. 通过implements让子类来实现
  4. 可以理解成,接口是一个特殊的抽象类
  5. 接口突破了java的单继承的局限性
  6. 接口和类之间可以多实现,接口和接口之间可以多继承
  7. <mark>接口是对外暴露的规则,是一套开发规范</mark>
  8. <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关键字不可以和哪些关键字一起使用呢?以下关键字,在抽象类中。用是可以用的,只是没有意义了。

  1. private:被私有化后,子类无法重写,与abstract相违背。
  2. static:静态的,优先于对象存在。而abstract是对象间的关系,存在加载顺序问题。
  3. final:被final修饰后,无法重写,与abstract相违背。

7.2 接口和抽象类的区别

  1. 抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
  2. 抽象类要被子类继承,接口要被类实现。
  3. 接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
  4. 接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
  5. 抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
  6. 抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
  7. 抽象类里可以没有抽象方法
  8. 如果一个类里有抽象方法,那么这个类只能是抽象类
  9. 抽象方法要被实现,所以不能是静态的,也不能是私有的。
  10. 接口可继承接口,并可多继承接口,但类只能单根继承。