day13总结

1.软件设计六大原则

        

        1 单一职责原则

原则思想 : 一个方法只做一件事,一个类只负责一个职责,这样当前职责改动,不会对其他程序产生影响

常识原则,几乎所有程序员都会遵循这个原则

优点 : 降低类和类之间的耦合度,提高可读性,可维护性,可扩展性,降低可变性的风险

        2 里氏替换原则

原则思想 : 能使用父类的地方,就一定可以使用子类

子类还可以扩展父类的功能,但是不能更改父类的功能,并且子类还可以有自己特有的功能

优点 : 增加了程序的健壮性,即使有了新的子类,原子类不受影响,可以正常执行

        3 依赖倒置原则

原则思想 : 高层次不应该依赖低层次,都应该依赖于抽象

优点 : 拥抱多种变化,可以减少需求变化带来的工作量

        4 接口隔离原则

原则思想 : 类和接口之间应该建立在最小接口上

        5 迪米特法则

原则思想 : 又称为最少知识原则,一个对象尽可能的少了解其他对象

一个类中尽量减少对其他类的依赖

        6 开闭原则

原则思想 : 对修改关闭,对扩展开放

尽量通过扩展软件实体来解决需求的变化,而不是通过修改已有的代码来完成变化

2.什么是多态 : 
          多态就是里氏替换原则的一种体现
                  能使用父类的地方就一定可以使用子类
  
          多态 就是 父类引用指向子类对象
              父类引用 : 使用父类类型 创建的引用类型变量
              指向 : 通过这个引用可以找到谁
              通过父类创建的一个引用类型变量,找到了子类的对象
              父类类型  变量名 =  new 子类();
              Animal a = new Animal();
              Animal a = new Cat() ; 多态
  
          有变量的地方,就能发生多态,并且多态发生在赋值的时候
  
          多态的缺点 : 丢失子类特有的属性

3.多态的几种形式 : 
          1 直接多态 : 父类  变量 = new 子类();
          2 形参/实参 : 参数列表用父类声明, 调用方法 传递子类对象
                  public void m1(Animal a){}
                  m1(new Cat());
          3 返回值多态 : 返回值类型是父类类型,但是返回的对象 是子类对象
                  public  Animal m2(){
                      return new Cat();
                  }
                  Animal a = m2();
 4.多态进行属性调用 : 
          1 父类没有的,都调用不了(因为多态缺点,丢失子类特有的属性)
          2 父类有的,子类没有的,执行父类
          3 父类和子类都有,除了成员方法执行子类,其他全部执行父类(因为只有成员方法可以覆写) 

// 直接多态
        Animal a = new Cat();
        
        
        // 返回值多态
        Animal i = m1();
        
        // 形参实参多态
        m2(new Cat());
    }
    public static void m2(Animal a ){
    }
    public static Animal m1(){
        return new Cat();
    }

5.多态的优点


    // 需求 : 编写方法,要求能够接收所有的对象,并调用该对象的move方法
    // 如果后续想接收其他动物,就需要改动源码,扩展性不强
    // 比如我有钱了,想养老虎,那么我这里就需要更改,添加一个接受老虎的接口
     public static void test(Cat_1 cat) {
     cat.move();
     }
    
     public static void test(Dog_1 dog) {
     dog.move();
     }
    
    // 多态形式,只要传递的对象是Animal_1的子类都是可以的
    // 所以后续想接收其他动物,这里也不需要改动,更能拥抱变化
    // 就算我有钱了想养老虎,老虎属于动物,我这里还是不用更改
     public static void test(Animal_1 animal_1) {
         animal_1.move();

6.缺点:丢失子类特有的属性

// 编译阶段,和对象没有关系,就算赋值为null都可以,大不了运行时出现空指针异常,但是是可以运行的
        // 说明 编译时检查语法结构的时候,和是哪个对象没有关系,就看类型
        Sub_03 sub = null;
        System.out.println(sub.age);
        // 同理 ,就算后面不是null,编译阶段也和对象没有关系,都没有运行,哪来的对象
        // 目前编译器只知道对应的 Sup_03 中 没有age属性,所以编译时就报错了
        // 所以 导致多态的缺点 : 丢失子类特有的属性
        Sup_03 sup = new Sub_03();
        // System.out.println(sup.age);
        
        // 类型转换为子类类型,就能访问
        Sub_03 sub1 = (Sub_03) sup;
        System.out.println(sub1.age);

7.多态 : 又叫向上转型
              子类到父类 是向上
              父类到子类 是向下
  
          想要向下转型 必须先发生向上转型

public static void main(String[] args) {
        Animal a = new Cat();
        // 强制类型转换为cat类型
        // Cat c = (Cat)a;
        
        // java.lang.ClassCastException: _10_Polymorphic.Cat cannot be cast to _10_Polymorphic.Dog
        // 强制转换 可能会出现类型转换异常
        // Dog d = (Dog) a;
        
        // instanceof : 判断某个对象是否由某个类实例化而来
        if (a instanceof Dog) {
            Dog d = (Dog) a;
            System.out.println("狗");
        }else if (a instanceof Cat) {
            Cat c1 = (Cat)a;
            System.out.println("猫");
        }

8.多态属性的调用

        1.父类没有的,都调用不了(因为多态的缺点,丢失子类特有属性)

        2.父类有的,子类没有的执行父类

        3.父类和子类都有的,除了成员方法执行子类,其他全部执行父类(应为成员方法可以覆写)

9.比较隐秘的多态


class Sup_04 {
    int i = 22;
    public void m1() {
        // this 保存的是子类的内存地址,因为用哪个对象调用的这个方法,this就指向谁
        // this 是对象中第一个成员变量,保存当前对象的内存地址
        // 既然是变量,肯定有类型,可以保存当前类对象的类型有 
        // 1 当前类类型(this所在的类就是当前类)
        // 2 父类类型(多态,缺点 : 丢失子类特有的属性)
        // 而 this 可以调用当前类中特有的属性,所以 this的类型 应该是当前类类型
        // this在哪个类,哪个类就是当前类,而现在这个程序 this在 Sup_04 类中
        // 所以 就等于是 Sup_04 this;
        // 而 谁调用的这个方法,this就指向谁,这个m1方法最终是由 new Sub_04() 调用的,所以 this指向 new Sub_04()
        // 相当于 : Sup_04 this = new Sub_04();
        // 总结 : 通过子类,调用父类的方法的时候,此时父类这个方法中的上下文环境,就是多态环境
        System.out.println("m1--"+this);
        System.out.println(this.i);
        m2();

10.抽象 : 抽象类往往表示设计中得出的抽象概念
          比如 动物 , 它只是一个抽象的概念,并没有具体的一个东西叫动物,所以它并不能代表一个实体
          这种情况下 我们就适合把他作为一个抽象类
              比如 Animal 表示所有动物,但是没有一个具体东西叫动物,
              它可以作为所有动物的祖类,可以把所有动物共有的属性和行为保存到Animal中
              然后再有Cat , Dog之类的 具体的动物类,都继承Animal类,并且Cat还具有他们特有的属性
              那么此时 Cat 表示猫,而一个Cat对象就表示具体的某一个猫
              但是 Animal 不应该有对象,因为没有一个东西是叫动物,动物是一个统称
              那么此时 Animal 就适合作为抽象类

11.abstract : 修饰符,修饰的类是抽象类,修饰的成员方法是抽象方法
       抽象方法 : 使用abstract修饰的成员方法,并且该方法没有方法体,就是没有大括号
       抽象类 : 不能被实例化,只能用于被继承
              一般抽象类中,有功能的定义,但是没有功能的实现,要求必须让子类覆写
                  比如我们的Animal和Cat,使用多态可以降低耦合度,但是Animal中 ,只需要有move的方法,不需要有具体的实现
                  因为具体实现应该由Cat实现,但是Animal中还必须得有,要么多态使用不了,丢失子类特有的属性
                  但是如果Animal中写了move方法,那么子类中 覆写不覆写都可以,根本没办法强制要求
                  这个时候 可以再Animal中编写一个抽象方法,但是抽象方法必须要在抽象类中的
                  所以 继承这个抽象类之后,必须要实现抽象类中的所有抽象方法
                      实现 : 子类对抽象方法加上方法体,完成功能实现
  
          含有抽象方法的类型一定是抽象类  正确
          抽象类中一定含有抽象方法  错误
  
          抽象类和普通类几乎完全一样,只有两点不同
              1 不能创建对象
              2 可以有抽象方法
  
  非抽象类继承抽象类 必须实现所有的抽象方法
  抽象类继承一个抽象类 可以实现 0~N个抽象方法

12.抽象语法

abstract class A{
    public abstract void m1();
    public abstract void m2();
}
// 抽象类继承一个抽象类 可以实现 0~N个抽象方法
abstract class B extends A{
    @Override
    public void m1() {
        
    }
}
// 非抽象类继承抽象类 必须实现所有的抽象方法
class C extends A{

    @Override
    public void m1() {
        
    }

    @Override
    public void m2() {
        
    }

13.注意 :
  
  abstract 和 final 不能同时出现
  
  abstract修饰的类 是抽象类,就是用来被继承的 而 final修饰的类 不能被继承
  
  abstract修饰的方法 是抽象方法,而抽象方法就是用来被覆写实现的, 而 final修饰的成员方法 不能被覆写

static public  void main(String[] args) {

    }
}

// abstract final class A1 {
abstract class A1 {
    // public abstract final void m1();
    abstract public  void m1();

14. 引用数据类型 : 类,数组,接口
  
  接口是一种引用数据类型,可以看做是一个特殊的类,是为了解决java中单继承功能变弱问题
          一个类只能继承一个父类,但是可以实现N个接口
  
  1 [修饰符] interface 接口名 { }
  2 1.8之前 接口中只有抽象方法和常量(public static final)
              -2147483648~2147483647
  3  接口中 public static fianl  还有 abstract 都可以省略(接口中没有变量,只有常量,写个方法就是抽象方法)
  4 接口没有构造方法,不能创建对象
      5 一个类 实现一个接口,需要实现所有的抽象方法
  6 一个抽象类 实现一个接口,需要实现0~N个抽象方法

15.Java1.8接口新特性

          1.8 之前 只能有抽象方法
          1.8开始  可以有静态方法和默认方法(可以理解为类中的成员方法)
                  静态方法 和 常量 使用接口名.xxx 调用就行
                  而默认方法,需要子类对象调用才行
          1.9开始 支持private方法

16.用法

17.// psf 可以省略
    String B = "xxx";
    
    public abstract void m1();
    // public 和 abstract 可以省略
    void m2();
    
    // 静态方法
    public static void m3(){
        System.out.println("静态方法");
    }
    
    public default void m4(){
        System.out.println("默认方法");
    }

18.interface A{
    void m1();
}
interface B {
    void m2();
}
// 接口和接口之间是多继承 多个以逗号隔开
interface C extends A,B {
    void m3();

19.多实现

// 类和接口直接是多实现,保留类继承,所以 当抽象类和接口都能满足需求的时候,优先使用接口 
// 一个非抽象类实现接口后,需要实现所有抽象方法
// 一个抽象类实现接口后,需要实现0~N个抽象方法
class D extends Object  implements A,B{

    @Override
    public void m2() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void m1() {
        // TODO Auto-generated method stub
        
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值