Java基础 - 面向对象

2019-04-15  本文已影响0人  ADMAS

面向对象

对象实例化过程

对象的生命周期

匿名对象

static修饰的类成员

深入变量

分类

成员变量

局部变量

变量的作用域和生命周期

作用域:

生命周期:

变量的生命周期指的是一个变量被创建并分配内存空间开始,到该变量被销毁并清除其所占内存空间的过程。

    **类变量** -> 类中定义, 被static修饰 -> 从字节码加载开始,字节码被卸载时结束.
    
    
    **实例变量** -> 类中定义, 无static修饰 -> new对象开始,对象被销毁时结束
    
    
    **局部变量** -> 定义在方法,代码块,方法形参 -> 所在方法被调用开始,方法调用结束时结束

局部变量的初始化和在JVM中的运行机制

修饰符

访问权限修饰符:

  1. private(类私有):本类内部可以访问,不能被子类继承。
  1. 无(包私有):本类内部可以访问,同包其他类也可以访问,能被同包的子类继承。
  1. protected(包和子类私有):本类内部可以访问,不同包的子类也可以访问,同包其他类也可以访问,能被子类所继承。
  1. public(公共):任何地方都可以访问,能继承到子类。

    注意:类的访问修饰符只有 public和缺省,即public class A{}或者class A{}

    接口的访问修饰符只有public或缺省

final 修饰符:

abstract修饰符

static 修饰符

面向对象-继承

子类继承了:

方法重写

企鹅(Penguin)和鸵鸟(Ostrich)是鸟类中的一个特殊品种,所以企鹅/鸵鸟类是鸟类的一个子类,但是鸟类有飞翔的功能,但是对应企鹅/鸵鸟,飞翔的行为显然不适合于它。

此时就要进行方法的覆写或者重写,意思就是在子类中重新编写方法体

重写原则:

建立在能继承的基础上,不能继承的方法不能改写!

super关键字

this关键字

隐藏(小结)

面向对象-多态

编译类型和运行类型

如:Animal a = new Dog();

此时对象a的类型有两种:

多态的特点

Animal a = null;

a = new Cat();//此时a表示猫

a = new Dog();//此时a表示狗

可以看出对象a会出现多种形态的情况。此时我们把这种父类指向了子类对象的引用的现象称为多态。
  1. 用父类的类型来声明变量,并引用了子类的对象,在运行时体现出了子类的特征.
  1. 用接口的类型来声明变量,并引用了实现类的对象,在运行时表现了实现类的行为特征.

多态的方法调用问题

若SuperC是SubC的父类或其接口:

    SuperC s = new SubC();
    s.doWork();

构造代码块

特点:

优先于构造方法执行,每次实例化对象之前都会执行构造代码块。
其实编译时就是把这个代码块中的代码放到了构造方法中代码的前面。

类实例化时的初始顺序:

成员变量的赋值 -> 构造代码块 -> 构造方法

静态代码块

使用static修饰的构造代码块,称为静态代码块,用于初始化类中的静态成员变量.

特点:

  1. 当字节码被加载到JVM的时候自动执行
  1. 只会执行1次

类实例化时的初始顺序:

静态代码块 -> 构造代码块 -> 构造方法

Java设计模式

分类

单例模式`

目的:保证某一个类在整个应用中有且只有一个实例(一个类在内存只存在一个对象),即所有指向该类型实例的引用都指向同一块内存空间
private static CLASS_NAME instance ;

private $CLASS_NAME$($param1$){
$init$
}

public static $CLASS_NAME$ getInstance($param1$){
    if (instance == null) {
        synchronized ($CLASS_NAME$.class){
            if (instance == null) {
                instance = new $CLASS_NAME$($param2$) ;
             }
        }
    }
    return instance ;
}

享元模式

以基本类型包装类为例:

Byte、Short、Integer、Long:缓存[-128,127]区间的数据;

Character:缓存[0,127]区间的数据;

当取值范围在这区间时,不会重新创建对象,而是直接从缓存中获取对象.

特点:

把经常使用的数据先缓存起来,以后要用的时候直接去缓存中获取,缓存中没有再创建,使用享元模式后能够提高系统的性能和不会带来更多的复杂度时

模板方法设计模式

public abstract Class template{
    //模板方法 子类不能复写
    public final protected templateMethod(){
        ...  //相同逻辑
        
        absMethod(); 

        ...//相同逻辑
    }
    protected abstract void absMethod(); //抽象方法,由子类重写实现
}

在父类的一个方法中定义一个总体算法的骨架,而将某一些步骤延迟到子类中,因为不同的子类实现细节不同。

抽象父类至少提供的方法:

注意:抽象父类提供的模版方法只是定义了一个通用算法,其实现必须依赖子类的辅助。

组合模式

解决代码复用问题:

组合关系/包含关系:"has A"关系.

在一个类中包含了另一个类型(基本类型和引用类型)的成员变量,通过对传入这类型的对象后可以在本类中使用其他类的功能

interface SIM{
    打电话();
}
class 移动 implement SIM{
    重写方法...
}
class 手机{
    //手机要打电话,打电话的方法在SIM接口中,此时我们使用组合模式,即不继承SIM
    SIM sim ; 
    手机(SIM sim){//传入SIM的实现对象,手机就可以达到打电话了
        this.sim = sim;
    }
    打电话(){
        sim.打电话();
    }
}

抽象类

抽象类需要的部分功能,由于自己不能实现,而交由子类去实现,此时就需要定义抽象方法,让子类去重写,实现具体功能.

特点:

使用abstract关键字修饰的类。

接口

例子:

主板提供了USB规范的插槽(F类中向外提供了一个传递I接口类型参数的公共方法),一个遵循USB规范的鼠标(一个实现了I接口的IMPL类),就可以插入主板(向F类中传递实例对象),与主板正常通信(IMPL类可与F类进行数据交互),主板不需要关心鼠标是怎么生产的,内部是怎么样的(F类只需调用IMPL类已实现的接口方法即可,不需要关心怎么实现).鼠标坏了也不会影响主板.

接口定义一种规范,规定某一类事物类必须具备某些功能,但它不管类如何具体实现这些功能。

特点:

接口和抽象类

相同点:

  1. 都位于继承的顶端,用于被其他实现或继承。
  1. 都不能实例化。
  1. 都可以定义抽象方法,其子类都必须覆写这些抽象方法。

区别:

  1. 接口没有构造方法,抽象类有构造方法。
  1. 抽象类可包含普通方法和抽象方法,接口只能包含抽象方法;
  1. 一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口(接口弥补了Java的单继承)。

    变量:接口里默认是public static final,抽象类是默认包权限。

    方法:接口里默认是public abstract,抽象类默认是默认包访问权限。

    内部类:接口里默认是public static,抽象类默认是默认包访问权限。

二者的选用:

优先选用接口,尽量少用抽象类。若需要定义子类的行为,又要为子类提供共性功能时选用抽象类。

面向接口编程

我们以后所看到的多态形式都是大多数都是接口和实现类之间关系

接口类型 变量 = new 接口实现类

面向接口编程的好处在于能屏蔽不同子类之间的差异,使用一种规范去表示他们的行为,达到通用编程(多态的好处)的好处

我们以后在类中出现要创建对象的时候,统统都不new对象,改为使用工厂模式来生产对象,但是要生产怎样的对象才是我们要的呢?在类中留下一个规范,即接口。

内部类

内部类(静态内部类除外)可以访问外部类的私有数据,外部类不能直接访问内部类的实现细节,比如字段。

四种内部类:

  1. 非静态内部类:

    ClsOut.ClsIn in = new ClsOut().new ClsIn();

  2. 静态内部类:

    ClsOut.ClsIn in = new ClsOut().ClsIn;

  3. 局部内部类:

    在方法中定义的类,若在局部内部类对象中访问方法中的局部变量, 则变量必须加final修饰,否则方法调用结束,变量就被回收了

  4. 匿名内部类适合于仅使用一次使用的类:

    适合只使用一次的类。

    不能是抽象类,因为系统在创建匿名内部类的时候,会立即创建匿名内部类的对象。

    不能定义构造器,因为匿名内部类没有类名。

    注意:匿名内部类必须继承一个父类或者实现一个接口,但最多只能一个父类或实现一个接口。

枚举类

上一篇 下一篇

猜你喜欢

热点阅读