CGB2005 0820 JAVA16AOP练习

以后要复习
AOP

1.核心业务分析1 查询问题 提高性能 考虑原有的基础上(数据库)存入缓存

从分析项目中的问题开始
从SysUserServiceImpl开始
在这里插入图片描述
如上图 这是一个查询操作
更新的频率比较高 经常需要查询的话
考虑把查询到的数据缓存起来
在这里插入图片描述
同时把上图的分页信息也缓存起来
如下图描述 第一次基本都是要在数据库查询
第二次 将查询到的数据存储到缓存并返回
走缓存不走数据库 性能更好

在这里插入图片描述

思想如下图 每个查询对象都可以这样写* 这叫共性 要去封装共性提取特性***

在这里插入图片描述

还有核心业务分析2 就是保存数据问题

saveObject
如下图 一是保存自身信息 二是保存角色对应关系数据
假如 一保存成功了 而二保存失败了 要不要考虑两个操作都撤销
不可能一个成功一个失败 要 要么都成功 要么都失败(必须一致)
在这里插入图片描述

考虑事务 保存操作的一致性
在这里插入图片描述
在这里插入图片描述
如上图 成功则提交 失败则回滚
规范就是1.开始事务 2.提交事务 3.失败则回滚事务

考虑:假如一个方法写入这三条语句 可以 如果一百个方法 都是同样的开启提交回滚 都是同样的逻辑
重复性太高 如果再加一个 记录开始执行时间 和记录结束执行时间 的语句 那么这一百个方法都要对应去改(且重复)
在这里插入图片描述
在这里插入图片描述
如上图 假如上图有类似的方法 一百到两百个 就一直在重复性的编写
可以在每个方法加入一个记录日志的方法 然后方法里面加入记录日志时间的操作
封装这种共性和相同的逻辑 遵循ocp原则 对扩展开放 对修改关闭

OCP原则分析 加额外业务 而不能修改代码 还得在上面添加功能

继承 父子关系
1.定义一个接口
在这里插入图片描述
2.接口的实现类
核心业务代码
在这里插入图片描述
3.测试类
在这里插入图片描述
在这里插入图片描述
结果可以呈现 没有问题

但是不可取
所以业务做好了 就不允许修改了
1.可读性更差
把原有的业务类(核心业务给改了) 下一次要对方法作业务的控制 或者方法里面再加一个任务调度 或者发送失败的时候给出一个信息
然后会从原有3行变成很多行很多行
多态不理解了 父类对象引用 指向子类对象
2.主次逻辑分不清楚

MailService ms = new DefaultMailService();
ms.sendMsg("hello cgb2005");

回归回顾 继承和多态

菜鸟教材 Java继承

继承回顾

继承需要符合的关系是:is-a 也是提取共性思想 父子关系

继承 extend 单一继承

类的继承格式

class 父类 {
}
 
class 子类 extends 父类 {
}

开发动物类,其中动物分别为企鹅以及老鼠,要求如下:
企鹅:属性(姓名,id),方法(吃,睡,自我介绍)
老鼠:属性(姓名,id),方法(吃,睡,自我介绍)

在这里插入图片描述
根据需求写下的公共父类方法
在这里插入图片描述

如上图 最关键的是 思想 属性私有化 方法公共化

public Animal(String myName, int myid) { 
        name = myName; 
        id = myid;
    } 

原理理解:上面的代码 构造方法Animal(){}是为了 下面的方法可以在属性私有(保证安全性的情况下) 被公共类调用 原理如下图 理解错了 有get set才是

***最基础的继承
继承的作用:
1、提高了代码的复用性
2、使类与类之间产生了关系,有了这个关系,才有多态的特性。

注:
不要为了获取其它类的功能,简化代码而继承。必须是类与类之间有所属关系,所属关系是is a(父类是子类的一部分)。
父类是由子类不断抽取而来的。***
在这里插入图片描述
is a 把共性提取 相同重复的一部分

class People {            //共性描述,即父类、超类、基类
    String name;
    int age;
}

在这里插入图片描述

class A{
  demo1(){}
  demo2(){}
}
class B extends A{
  demo1(){} 
  demo3(){}
}

在这里插入图片描述
是去继承共有的(父类 包含相同的) 而不是去继承没有的
先有父类,再有子类。
在这里插入图片描述
先查问体系父类的描述,因为父类中定义的是该体系中的功性功能。通过了解该共性功能,就可以了解该体系的基本功能。那么这个体系也就可以基本使用了。

在具体调用时,要创建最子类的对象。原因一,父类有可能不能创建对象;原因二,创建子为对象可以使用更多的功能,包括基本的和特有的。

查阅父类功能,创建子类对象使用功能。由父类去延申子类,除了基本的(共性),还要特有的(特性)

示例1

package day01;


public class ExtendsDemo1 {
	public static void main(String[] args) {
		Zi z = new Zi();
		System.out.println(z.num1+"......"+z.num2);
	}
}
class Fu {
	int num1 = 1;
}

class Zi extends Fu {
	int num2 = 2;
}

在这里插入图片描述

示例2、 如子父成员变量同名,且非私有,子类访问子类变量要用this,子类访问父类变量要用super

public class extendsdemo {

    public static void main(String[] args) {
        Zi z = new Zi();
        z.show();
    }
}

class Fu {
    int num = 1;

}

class Zi extends Fu { // 子父类有相同的变量。
    int num = 2; // 和父类变量名相同

    void show() {
        System.out.println(this.num); // this代表本类对象的引用
        System.out.println(super.num); // super代表父类对象的引用
    }

}

在这里插入图片描述
尝试加入方法
在这里插入图片描述

示例3:

子父类出现完全一样的函数时,当子类对象调用子类函数,会运行子类的内容。
如同父类函数被覆盖一样,这种情况是函数的另一个特性————重写(覆盖)

当子类继承父类,沿袭了父类的功能到子类中,但子类虽具备该功能,但是功能的内容却和父类不一样。这时,就没有必要在子类中重新定义该功能,而只要使用覆盖特性,保留父类的功能定义即可。

此时父类的方法还存在于内存中,只是没有运行。

在这里插入图片描述
在这里插入图片描述

构造方法回顾

在这里插入图片描述
构造方法和构造函数时同一概念

构造函数

一、什么是构造函数
Java构造函数,也叫构造方法,是java中一种特殊的函数。函数名与相同,无返回值。

作用:一般用来初始化成员属性和成员方法的,即new对象产生后,就调用了对象了属性和方法。

在现实生活中,很多事物一出现,就天生具有某些属性和行为。比如人一出生,就有年龄、身高、体重、就会哭;汽车一出产,就有颜色、有外观、可以运行等。这些,我们就可以将这些天然的属性和行为定义在构造函数中,当new实例化对象时,也就具有这些属性和方法了,没必要再去重新定义了,从而加快了编程效率。

构造函数是对象一建立就运行,给对象初始化,就包括属性,执行方法中的语句。

而一般函数是对象调用才执行,用".方法名“的方式,给对象添加功能。

一个对象建立,构造函数只运行一次。

而一般函数可以被该对象调用多次。
构造函数
在这里插入图片描述
二、构造函数的特点
1、函数名与类名相同

2、不用定义返回值类型。(不同于void类型返回值,void是没有具体返回值类型;构造函数是连类型都没有)

3、不可以写return语句。(返回值类型都没有,也就不需要return语句了)

注:一般函数不能调用构造函数,只有构造函数才能调用构造函数。

1、无参构造函数中只定义了一个方法。new对象时,就调用与之对应的构造函数,执行这个方法。不必写“.方法名”。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、有参构造函数,在new对象时,将实参值传给private变量,相当于完成setter功能。

在这里插入图片描述

输出:
aerchi
18

最常见的构造函数方式

我们也可以将show()方法中的输出语句直接放在构造函数中,new对象时,即可直接输出值,如下

public class ConfunDemo3 {
    public static void main(String[] args){
        //实例化对象时,new Person()里直接调用Person构造函数并转转实参,同时执行输出语句
        Person z=new Person("aerchi", 18);
    }
}
 
class Person{
    private String name;
    private int age;
    //有参数构造函数,实现给private成员变量传参数值的功能,同时直接输出值
    public Person(String n,int m){  
        name = n;
        age = m;
        System.out.println(name+"\n"+age);
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
构造器
子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。

如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

实例
class SuperClass {
private int n;
SuperClass(){
System.out.println(“SuperClass()”);
}
SuperClass(int n) {
System.out.println(“SuperClass(int n)”);
this.n = n;
}
}
// SubClass 类继承
class SubClass extends SuperClass{
private int n;

SubClass(){ // 自动调用父类的无参数构造器
System.out.println(“SubClass”);
}

public SubClass(int n){
super(300); // 调用父类中带有参数的构造器
System.out.println(“SubClass(int n):”+n);
this.n = n;
}
}
// SubClass2 类继承
class SubClass2 extends SuperClass{
private int n;

SubClass2(){
super(300); // 调用父类中带有参数的构造器
System.out.println(“SubClass2”);
}

public SubClass2(int n){ // 自动调用父类的无参数构造器
System.out.println(“SubClass2(int n):”+n);
this.n = n;
}
}
public class TestSuperSub{
public static void main (String args[]){
System.out.println("------SubClass 类继承------");
SubClass sc1 = new SubClass();
SubClass sc2 = new SubClass(100);
System.out.println("------SubClass2 类继承------");
SubClass2 sc3 = new SubClass2();
SubClass2 sc4 = new SubClass2(200);
}
}
输出结果为:

------SubClass 类继承------
SuperClass()
SubClass
SuperClass(int n)
SubClass(int n):100
------SubClass2 类继承------
SuperClass(int n)
SubClass2
SuperClass()
SubClass2(int n):200
多继承的特性 implements
在这里插入图片描述

多态 理解

Java多态的三个必要条件:

1、 继承

2、 子类重写父类方法

3、 父类引用指向子类对象

package test.xing;

class Father{
    protected int age;
    public Father(){
        age = 40;
    }
    
    void eat(){
        System.out.println("父亲在吃饭");
    }
}
class Child extends Father{
    protected int age;
    public Child(){
        age = 18;
    }
    
    void eat(){
        System.out.println("孩子在吃饭");
    }
    void play(){
        System.out.println("孩子在打CS");
    }
}

public class TestPolymorphic {
    public static void main(String[] args) {
        Father c = new Child();
        c.eat();
        //c.play();
        System.out.println("年龄:"+c.age );
        
    }

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
如上二图 eat()和play()只是普通构造方法 并不是构造函数(特殊的构造方法)

如下图 父类引用的对象拥有了子类方法和属性
在这里插入图片描述
多态的优点

  1. 消除类型之间的耦合关系
  2. 可替换性
  3. 可扩充性
  4. 接口性
  5. 灵活性
  6. 简化性
    多态存在的三个必要条件
    继承
    重写

父类引用指向子类对象

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

**关注点 调用子类的同名方法 还是显示子类的方法 显示父类的属性 **

package Animal;

import java.util.Scanner;

public class Test {
	public static void main(String[] args) {
		Dog dog = new Dog();
		dog.eat();
		dog.LookHome();
		
		System.out.println("====================");
		Cat cat = new Cat();
		cat.eat();
		cat.catchMouse();
		
		System.out.println("=========多态复用性1===========");
		Animal a = new Dog();
		a.eat(); 
		
		System.out.println("=========多态复用性1===========");
		Animal a1 = new Cat();
		a1.eat(); 
	}
}

 abstract class Animal{
	abstract void eat();
}

 class Dog extends Animal{
		public void eat() {
			System.out.println("啃骨头!");
		}
		public void LookHome() {
			System.out.println("看家!");
		}
	}
	 
	class Cat extends Animal{
		public void eat() {
			System.out.println("吃鱼!");
		}
		public void catchMouse() {
			System.out.println("抓老鼠!");
		}
}
	

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
多态就是为了更统一 当然变量名需要变动
在这里插入图片描述
通过继承方式扩展 super
在这里插入图片描述
通过组合 耦合的方法 has a 去不修改核心代码 拓展功能
构造函数
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
如上图 还是有点不理解
在这里插入图片描述
如下图 是has a 耦合思想
在这里插入图片描述
明早把耦合 has a的点回顾一下 还要传参数的多态
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

多态就是规范 继承 重写 父类引用指向子类对象 new谁就调用谁

只能(点出)调用继承后重写的方法(共有的),而子类特有的无法去调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值