java 面向对象 (2)

112 阅读9分钟

  面向对象的三大特征 

       继承、封装、多态;

     1. 继承:让我们更容易实现类的扩展,实现代码重用;

           主要作用: 

              1. 代码复用,扩展类 。

              2. 方便建模;

关键字 extends

    instanceof 运算符:左边是对象,右边是类,当对象是右边类或子类所创建对象时,返回true,否则 false;

   继承使用要点 

        1. 父类也称作超类、基类。 子类:派生类 ;

        2. Java 中只有单向继承,没有像C++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难以维护 ;

     3. Java中类没有多继承、接口有多继承;

     4. 子类继承父类,可以得到父类的全部属性和方法(除了父类的构造方法,但不见得可以直接访问(比如,父类私有的属性和方法);

      5. 如果定义一个类时,没有调用extends,则它的父类时:java.lang.Object. 

方法重写 override

子类重写父类的方法,可以用自身行为替换父类行为。重写是多态的必要条件。

 方法重写需要符合下面的三个要点: 

      1. 方法名、形参列表相同;

      2. 返回值类型和声明异常类型子类小于等于父类;

      3. 访问权限,子类大于等于父类;

final 关键字作用: 

    1. 修饰变量:被它修饰的变量不可变。 一旦赋了值,就不能重新赋值;

    2. 修饰方法: 该方法不可被子类重写,但不是可以被重载! 

    3, 修饰类,修饰的类不能被继承; 比如(Math\String)

继承和组合 > 组合: 

       将父类对象作为子类的属性 。

      组合比较灵活。继承只能有一个父类,但是组合可以有多个属性,所以有人生成“组合优于继承,开发中可以不用继承”,但是不要走极端。

       对于“is-a” 关系建议使用继承,“has-a” 关系建议使用组合。

super 关键字

  1. super "可以看做" 是直接父类对象的引用。 可通过super 来访问父类中被子类覆盖的方法或属性;

    2. 使用super调用普通方法,语句没有为止闲置,可以在子类中随便调用; 

    3. 在一个类中,若时构造方法的第一行没有调用super(...) 或者 this(...);那么java默认会调用super(),含义时调用父类的无参构造方法;

继承树的追溯 

      属性/方法查找顺序: (比如:查找变量h) 

           1. 查找当前类中有没有属性h;

           2. 依次上溯每个父类中是否有h,直到Object 

           3. 如果没有找到,则出现编译出错 ;

           4. 上面步骤,只要找到h变量,则这个过程终止 

构造方法的调用顺序: 

        构造方法第一句总是super(...)来调用父类对应的构造方法吗所以,

        流程就是:先向上追溯到Object, 然后再依次向下执行类的初始化块和构造方法,知道当前子类为止;

== 和 equals

        == 代表比较双方是否相同,如果是基本类型则表示值相等,如果是引用类型则表示地址相等即同一对象 

        equals() 提供定义 “对象内容相等” 的逻辑,默认比较两个对象的hashcode.

 public boolean equals (Object obj) {
    return (this == obj)
 }

封装 (encapsulation) 

 封装的理念: 高内聚、低耦合; 

     高内聚:类的内部数据操作细节自己完成,不允许外部干涉;

     低耦合:仅暴露少量的方法给外部使用,尽量方便外部调用;

      优点:

         1. 提高安全性;

         2. 提高代码复用性;

         3.细节封装,便于修改内部代码,提高维护性;

         4. 简化外部调用,便于调用者使用,便于扩展和协作; 

实现

         使用访问控制符: private、default、protected、 public > 

         注意: 关于 protected的两个细节

                1. 若父类和子类在同一个包中,子类可以访问 父类的protected 成员,也可访问父类对象的 protected 成员; 

                2. 若子类和父类不在同一个保重,子类可访问父类的protected 成员,不能访问父类对象的protected 成员。  

开发中封装的简单规则 

         属性一般使用private访问权限。 

         属性私有后,提供相应的get/set方法来访问相关属性,这些方法通常是public修饰的,以提供对属性的赋值与读取操作(注意:boolean变量的get方法是is开头) 

          方法:一些只用于本类的辅助性方法可以用private修饰,希望其他类调用的方法用public修饰;

多态 (polymorphism)

        同一个方法调用,不同对象行为完全不同. 

        1. 多态是方法的多态,不是属性的多态 (多态与属性无关); 

        2. 多态的存在要有3个不要条件:继承, 方法重写,父类引用指向子类对象。

        3. 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。  

对象的转型 (casting)

       1. 父类引用指向子类对象,我们称这个过程为向上转型,属于自动类型转换 ;

       2. 向上转型后的父类引用变量只能调用它编译类型的方法,不能调用它运行时类型的方法。这时我们就需要进行强制类型转换,我们称之向下转型; 

抽象类和接口 

      抽象方法和抽象类 

      抽象方法:  

        1. 使用 abstract 修饰的方法,没有方法体,只是声明。 

        2. 定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。

       抽象类: 

         1. 包含抽象方法的类就是抽象类。 

         2. 通过抽象类,我们就可以做到严格限制子类的设计,使子类间更加通用。 

抽象类的使用要点: 

    1. 有抽象方法的类只能定义称抽象类;

    2. 抽象类不能实例化,即不能用new来实例化抽象类;

    3. 抽象类可以包含属性,方法,构造方法,但是构造方法不能用来实现new实例,只能用来被子类调用 ;

    4. 抽象类只能用来被集成 ;

    5. 抽象方法必须被子类实现。 

接口 interface

     接口就是一组规范,所有实现类都要遵守。

接口的作用: 

       接口就是比抽象类还抽象的抽象类,可以更加规范的对子类进行约束。全面的专业的实现了:规范和具体实现的分离 。

      接口实两个模块之间通信的标准,通信的规范。

     如果能把你要设计的模块之间的接口定义好,就相当于完成了系统的设计大纲没剩下的就是添砖加瓦的具体实现了。大家在工作以后,做系统时往往就是使用“面向接口”的思想来设计系统。

     接口和实现类不是父子类型,是实现规则的关系。

如何定义一个接口和使用接口 

      声明格式

          [访问修饰符] interface 接口名 [extends 父接口1,父接口2...] { 

                // 常量定义;

                //    方法定义;

 } 

        1 访问修饰符:只能是public或默认 ;

        2 接口名:和类名采用相同的命名机制 ;

        3 extends : 接口可以多继承 ;

        4 常量:接口中的属性只能是常量,总是:public static final 修饰,不写也是

        5 方法: 接口中的方法只能是 public abstract . 省略也是 public abstract 

要点

       1. 子类通过implements 来实现接口中的规范 ;

       2. 接口不能创建实例,但是可以用于声明引用变量类型。

       3. 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的。 

     4. JSK1.8 (不含8)之前,接口中只能包含静态常量,抽象方法,不能有普通属性,构造方法,普通方法。

 JDK1.8(含8) 后, 接口中包含普通静态方法,默认方法;

接口中定义静态方法和默认方法 

     1, JAVA8之前,接口里的方法要求全部是抽象方法 ;

     2, JAVA8 (含8),以后允许在接口里定义默认方法和静态方法 默认方法:

     Java8 及以上新版本,允许给接口添加一个非抽象的方法实现,只需要使用default 关键字,这个特征又叫做默认方法(也称为扩展方法)

    默认方法和抽象方法的区别是抽象方法必须要被实现。默认方法不是,作为替代方式,接口可以提供默认方法的实现,所有这个接口的实现类都可以得到默认方法;

静态方法

     JAVA8以后,我们也可以在接口中直接定义静态方法的实现,这个静态方法直接从属于接口(接口也是类,一种特殊类),可以通过接口名调用; 

   如果子类中定义了相同名字的静态方法,那就是完全不同的方法了,直接从属于子类,可以通过子类名直接调用;

接口的多继承 

     和类的继承类似,extends 父接口会获得父接口中的一切;

字符串String类详情 

 String 是最常用的类,就是把一堆字符串起来,一起使用;

    1. String 类又称作不可变字符序列。

    2. String 位于java.lang包中,Java程序默认导入java.lang下的所有类。 

    3. Java字符串就是Unicode字符序列,例如 “java” 就是4个Unicode字符 ‘j’、‘a’ 、‘v’、‘a’ 组成的。

   4. Java 没有内置的字符串类型,而是在标准Java类库中提供了一个预定义的类String, 每个用双引号括起来的字符串都是String类的一个实现;

内部类 

    我们把一个类放在另一个类的内部,成为内部类 ;

    成员内部类 : 非静态、静态 > 局部内部类 ;

    匿名内部类 内部类的两个要点: 

        1. 内部类提供了更好的封装,只能让外部类直接访问