一.面向对象

  • 需要记住的知识点
    • 面向对象的特征
      • 继承
        • java只支持单继承,不支持多继承,但是可以形成继承体系
        • 接口倒是可以继承(实现)多个。
        • 子类继承父类,在子类初始化时,会先调用父类的初始化,否则子类是无法使用父类的方法和成员变量的;
          • 默认子类调用父类的无参构造。如果父类显式声明了有参构造,系统不会默认生成父类的无参构造,因此子类默认调用父类的无参构造也就无从说起,编译时报错。此时需要使用super.父类已有构造 来实现父类的初始化
          • 成员方法和成员变量的调用遵循就近原则,如果子类和父类存在同名的成员变量和方法,子类会优先使用本类的成员变量和方法。如果想调用同名的父类方法和成员变量,就必须使用supper关键字,来显式的表示这是父类的。
          • 如果子类中的方法名与父类中的方法名同名,就叫方法重写(override)。方法重载(overload)是多态的表现。
      • 多态
      • 封装
        • 使用this关键字,表示当前对象。this.成员变量 表示当前对象的成员变量。this.成员方法 表示当前对象的成员方法。
        • 详见后续封装介绍:接口与抽象类
        • 所谓的重构,就是不断抽象的过程

             

    • 对象的构成
      • 构造器
        • 构造代码块
          • 构造代码块是所有构造函数同类型的抽象,每调用一次构造函数,都会在构造函数的第一行执行构造代码块。
          • 构造代码块是没有static关键字修饰的,但是静态代码块有。
          • 静态代码块是随着类的加载而加载的,主要对类初始化。构造代码块是对象的初始化,每创建一个对象都会先执行构造代码块。构造方法是用来创建对象的。创建对象时,先调用构造方法,然后构造代码块是构造方法中第一个执行的命令。
        • 代码示例
          • 创建对象
             1 package oop;
             2 
             3 /**
             4  * 测试构造代码块
             5  */
             6 public class CodeBlock {
             7     private String name;
             8     private int age;
             9 
            10     public CodeBlock(String name, int age) {
            11         this.name = name;
            12         this.age = age;
            13         System.out.println("我在执行有参构造。");
            14     }
            15 
            16     public CodeBlock() {
            17         System.out.println("我在执行无参构造。");
            18     }
            19 
            20     // 构造代码块
            21     {
            22         this.name="huabingood";
            23         this.age=18;
            24         System.out.println("执行到了构造代码块。");
            25     }
            26 
            27     @Override
            28     public String toString() {
            29         return "CodeBlock{" +
            30                 "name='" + name + '\'' +
            31                 ", age=" + age +
            32                 '}';
            33     }
            34 }
          • 测试
          •  1 package oopTest;
             2 
             3 import oop.CodeBlock;
             4 import org.junit.Test;
             5 
             6 public class CodeBlockTest {
             7     @Test
             8     public void test(){
             9         CodeBlock codeBlock = new CodeBlock();
            10         System.out.println(codeBlock.toString());
            11     }
            12     @Test
            13     public void test1(){
            14         CodeBlock codeBlock = new CodeBlock("华彬",22);
            15         System.out.println(codeBlock.toString());
            16     }
            17 }

             

      • 成员变量
        • 类的变量会初始化,但是方法的变量并不会初始化。
      • 成员方法
    • static是随着类的加载而加载的,优先于对象而存在,被该类的所有对象共享;可以通过类名(对象名)调用(不用new对象就可以直接使用,当然使用new出来的对象调用也是可以的);静态的都在方法去,因此不需要new即可调用;静态修饰的不能访问this关键字,静态方法只能访问静态成员变量,因为他是随着类的加载而加载的。
      • 静态方法只能访问静态成员变量,不能访问非静态成员变量,因为对象没有实例化的时候,非静态成员变量没有到堆内存中,但是静态成员变量已经在方法区了。先存在的不能调用不存在的东西。
      • 同样的道理,静态方法只能调用静态的方法,不能调用非静态的成员方法。但是非静态方法既能调用静态的方法也能调用非静态的成员方法
    • final关键字
      • 修饰方法则该方法不能被override
      • 修饰成员变量只能被赋值一次,赋值之后不能被更改
      • 修饰类则该类不能被继承
      • final修饰引用类型,表示引用类型的地址不能变。就比如教室是不会变的,但是学生可以改变
  • 类的初始化与实例化(这里的理解需要JVM知识)
    • 一个对象可以被使用之前,必须被正确的初始化。在实例化一个对象时,JVM会检查相关类型是否已经加载并初始化。如果没有,JVM立即进行加载并调用类构造器完成类的初始化。初始化完成之后才会对类进行实例化
    • 对象创建过程
      • 实例变量初始化
      • 实例代码块初始化
      • 构造函数初始化
    • 如果存在继承
      • 父类的成员变量,父类的实例代码块,父类构造,子类成员变量,子类代码块,子类构造函数 的过程。
  • 接口与抽象类
    • 接口
      • 是什么
        • 是一种规范。只说明应该做什么,但是并不规定如何做。这意味着接口里通常定义一组公用方法
        • 接口只有方法名没有方法体,实现接口就是让其既有方法名又有方法体。
        • 体现了规范和实现分离的设计哲学,降低了模块之间的耦合
      • 和其他的对比
        • 从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。接口只能定义一系列方法,算是定义行为,而不能包含具体的变量,不能拥有自己的属性,但是抽象类能够拥有变量。
      • 怎么用
        • 注意要点
          • 接口无法被实例化,不能new一个对象,但是可以使用多态来接具体实现子类
          • 接口的方法默认使用public修饰,且只能是public abstract修饰(因为是默认的可以省略),所有方法不能有方法体。但是抽象类是可以有非抽象方法的。
          • 接口中的实例变量默认是final,且只能是public static final 修饰(因为是默认的可以省略),但是抽象类中不一定。
          • 一个类实现接口的话就要实现接口的所有方法(抽象类不必实现所有的方法,但是具体实现子类必须实现所有的方法),而抽象类不一定?
          • 接口是多个类的公共行为规范,接口里的所有成员,常量,方法,内部类都必须是public修饰。但是不能有构造器和初始化代码块。因为不能实例化,所以具体实现子类若想调用父接口的成员变量,就只能调用静态的成员变量。
          • 通用设置

            [修饰符] interface 接口名 [extends 父接口1,父接口2…]{

            零到多个的常量定义…
            零到多个的抽象方法顶底…

            零到多个内部类,接口,枚举定义…

            零到多个默认方法或类定义…

            }

    • 抽象类
      • 是什么

        抽象类是用来捕捉子类的通用特性的 。它不能被实例化,只能被用作子类的超类。抽象类是被用来创建继承层级里子类的模板

    • 抽象类和接口的异同

抽象类

接口

对类的抽象

对行为的抽象

主要是模块内部的抽象

主要是模块之间的联系

自下而上的设计,需要在重构中抽取

自上而下,只需定义规则

子类继承必须实现所有的抽象方法

子类实现可以实现部分抽象方法,但是在一个继承体系内实现万所有的方法

使用abstrict关键字修饰接口

使用interface关键字修饰抽象类

默认是public修饰类

默认是public abstrice修饰类,可以省略

成员变量是public,protected 的

成员变量public static final,可以省略

可以有抽象方法,抽象方法不能有实现。可以有普通方法。

只能是public abstrict修饰的没有实现的抽象方法。(java8中存在静态方法)

类是单继承

接口是多继承

不能被实例化,但是可以有构造,有成员变量,方便子类调用父类的方法和成员变量。

不能被实例化,没有构造。

往抽象类中添加新方法,可以给出默认实现,不需修改已经存在的类

JDK8可以使用default给出默认实现,实现类可以不实现这个方法

  • 具体案例代码
     1 package oop.amimailDemo;
     2 /**
     3  * 描述:
     4  * 这个抽象类主要定义动物的抽象行为
     5  *
     6  * @author huabingood@qq.com
     7  * @version 1.0
     8  * @create 2018-09-06
     9  */
    10 public interface AnimalActive {
    11     // 接口成员变量默认是public static final 修饰
    12     int hige = 10;
    13 
    14     // 抽象方法默认是public abstract 修饰
    15     void eat(AnimalImple animalImple);
    16 
    17     void sleep();
    18 
    19     void jump(AnimalImple animalImple);
    20 } 
    21 
    22 package oop.amimailDemo;
    23 
    24 /**
    25  * 描述:
    26  * 这个是抽象类,实现了接口的部分方法,并定义一个抽象方法,给孩子
    27  *
    28  * @author huabingood@qq.com
    29  * @version 1.0
    30  * @create 2018-09-06
    31  */
    32 public abstract class AnimalImple implements AnimalActive {
    33     private String name;
    34     private int age;
    35 
    36     public AnimalImple() {
    37     }
    38 
    39     public AnimalImple(String name, int age) {
    40         this.name = name;
    41         this.age = age;
    42     }
    43 
    44     public String getName() {
    45         return name;
    46     }
    47 
    48     public void setName(String name) {
    49         this.name = name;
    50     }
    51 
    52     public int getAge() {
    53         return age;
    54     }
    55 
    56     public void setAge(int age) {
    57         this.age = age;
    58     }
    59 
    60     @Override
    61     public void eat(AnimalImple animalImple) {
    62         System.out.println(animalImple.getName() + "正在吃饭。");
    63     }
    64 
    65     @Override
    66     public void sleep() {
    67         System.out.println(this.getName() + "正在睡觉");
    68     }
    69 
    70 } 
    71 
    72 package oop.amimailDemo;
    73 
    74 /**
    75  * 描述:
    76  *
    77  * @author huabingood@qq.com
    78  * @version 1.0
    79  * @create 2018-09-06
    80  */
    81 public class Cat extends AnimalImple {
    82     public Cat() {
    83     }
    84 
    85     // 调用构造时,调用父类的构造,不再调用默认的父类构造
    86     public Cat(String name, int age) {
    87         super(name, age);
    88     }
    89 
    90     @Override
    91     public void jump(AnimalImple animalImple) {
    92         System.out.println(animalImple.getName() + "年龄是:" + animalImple.getAge() + "。能跳:" + AnimalActive.hige);
    93     }
    94 
    95     public void myOnly() {
    96         System.out.println("这是猫独有的方法");
    97     }
    98 } 

     


       

       

       

       

       

posted @ 2018-09-06 17:21  huabingood  阅读(171)  评论(0编辑  收藏  举报