java oop - yaokun123/php-wiki GitHub Wiki

JAVA面向对象

一、面向对象概念

对于面向过程思想,强调的是过程(动作)

对于面向对象思想,强调的是对象(实体)

面向对象的特点

1、面向对象就是一种常见的思想,符合人们的思考习惯。
2、面向对象的出现,将复杂的问题简单化。
3、面向对象的出现,让曾经在过程中的执行者,变成了对象中的指挥者。

二、类与对象的关系

只要明确该事物的属性和行为并定义在类中即可。

对象:其实就是该类事物实实在在存在的个体。

类于对象之间的关系

类:事物的描述
对象:该事物的实例。在java中通过new来创建。

示例:

class Car{
    int num;
    String color;

    void run(){
        System.out.println(num+"..."+color);
    }
}

class CarDemo{
    public static void main(String[] args){
        //在计算机中创建一个car的实例。通过new关键字。
        Car c = new Car();//c就是一个类类型的引用变量,指向了该类的对象。
        c.num = 4;
        c.color = "red";
        c.run();//要使用对象中的内容,可以通过“对象.成员”的形式来完成调用。
    }
}

对象的内存体现



成员变量和局部变量的区别

1、成员变量定义在类中,整个类中都可以访问。
   局部变量定义在函数、语句、局部代码块中,只在所属区域有效

2、成员变量存在于堆内存的对象中。
   局部变量存在于栈内存的方法中。

3、成员变量随着对象的创建而存在,随着对象的消失而消失。
   局部变量随着所属区域的执行而存在,随着所属区域的结束而释放。

4、成员变量都有默认初始化值。(堆内存会初始化变量的值)
   局部变量没有默认初始化值。(栈内存不会初始化变量的值)

注意:成员变量和局部变量同名时候

类类型参数

public static void show(Car c){//类类型的变量一定指向对象,要不就是null。
    c.num = 3;
    c.color = "black";
    System.out.println(c.num + "..." + c.color);
}

###匿名对象

匿名对象:没有名字的对象

new Car();//匿名对象,其实就是定义对象的简写格式

new Car().run();//当对象对方法仅进行一次调用的时候,就可以简化成匿名对象。

注意:匿名对象可以作为实际参数进行传递。

###基本数据类型参数传递和引用数据类型才参数传递图解

三、封装

封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式

好处:

1、将变化隔离
2、便于使用
3、提高重用性
4、提高安全性

封装原则:

将不需要对外提供的内容都隐藏起来。
把属性都隐藏,提供公共方法对其访问。

示例:

class Person{
    private int age;//私有属性
    public void setAge(int a){
        age = a;
    }

    public void getAge(){
        return age;
    }

    public void speck(){
        System.out.println("age="+age);
    }
}

四、构造函数

一个类中如果没有定义过构造函数,那么该类中会有一个默认的空参数构造函数。Person(){}
如果在类中定义了指定的构造函数,那么类中的默认构造函数就没有了。//Person(){}

什么时候定义构造函数呢?

在描述事物时,该事物已存在就具备的一些内容,这些内容都定义在构造函数中。

特点:

1、函数名与类名相同。
2、不用定义返回值类型。
3、没有具体的返回值

作用:

给对象进行初始化。

注意:

1、默认构造函数的特点

2、多个构造函数是以重载的形式存在

示例代码:

class Person{
    private String name;
    private int age;

    //定义一个Person类的构造函数
    Person(){//构造函数,而且是空参数的。
        System.out.println("person run...");
    }

    Person(String n){
        name = n;
    }

    Person(String n,int a){
        name = n;
        age = a;
    }

    public void speck(){
        System.out.println(name + "..." + age);
    }
}

class ConsDemo{
    public static void main(String[] args){
        Person p = new Person();//构造函数:构建创造对象时调用的函数。作用:可以给对象进行初始化
        p.speck()

        Person p1 = new Person("xiaoming");
        p1.speck()

        Person p2 = new Person("xiaozhang",10);
        p2.speck()
    }
}

一般函数与构造函数有什么区别?

构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化。
一般函数:对象创建后,需要函数功能时才调用。

构造函数:对象创建时,会调用只调用一次。
一般函数:对象创建后,可以调用多次。

构造函数内存图解

五、this关键字

特点:

this代表其所在函数所属对象的引用。
换言之:this代本类对象的引用。那个对象调用了this所在的函数,this就代表哪个对象。

什么时候使用this关键字?

当在函数内部需要用到调用该函数的对象时,就用this
当成员变量和局部变量重名,可以用关键字this来区分。

示例代码:

class Person{
    private String name;
    private int age;

    //定义一个Person类的构造函数
    Person(){//构造函数,而且是空参数的。
        System.out.println("person run...");
    }

    Person(String name){
        this.name = name;//用this来区分成员变量和局部变量
    }

    Person(String name,int age){
        this.name = name;
        this.age = age;
    }

    public void speck(){
        System.out.println(this.name + "..." + this.age);
    }
}

class ConsDemo{
    public static void main(String[] args){
        Person p = new Person();//构造函数:构建创造对象时调用的函数。作用:可以给对象进行初始化
        p.speck()

        Person p1 = new Person("xiaoming");
        p1.speck()

        Person p2 = new Person("xiaozhang",10);
        p2.speck()
    }
}

六、satic关键字

static 用于修饰成员(成员变量、成员函数)

被修饰后的成员具备以下特点

优先于对象存在,随着类的加载而加载
被所有对象共享
可以直接被类名调用

注意使用

静态方法只能访问静态成员。(非静态即可访问静态,又可访问非静态)
静态方法中不可以写this/super关键字。
主函数是静态的。

成员变量和静态变量的区别

两个变量的声明周期不同:
成员变量随着对象的创建而创建,随着对象的被回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。

调用方式不同:
成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。

别名不同:
成员变量也称为实例变量。
静态变量称为类变量。

数据存储位置不同
成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(静态区),所以也叫对象的共享数据。

什么时候使用

1、静态变量
当分析对象中所具备的成员变量的值都是相同的。这时这个成员就可以被静态修饰。
只要数据在对象中都是不同的,就是对象的特有数据,必须存储在对象中,是非静态的。
如果是相同的数据,对象不需要修改,只需要使用即可,不需要存储在对象中,定义为静态的。

2、静态函数
函数是否用静态修饰,就参考一点,就是该函数功能是否有访问到对象中特有的数据。
简单点说,从源代码看,该功能是否需要访问非静态的成员变量,如果需要就是非静态的,如果不需要,就可以将该功能定义成静态的。

静态代码块

随着类的加载而执行,而且只执行一次。

作用: 用于给类进行初始化。(当类不需要创建对象时候)

class StaticCode{
    static{
        System.out.println("hahahaha");
    }

    void show(){
        System.out.println("show run");
    }
}

class StaticCodeDemo{
    public static void main(String[] args){
        new StaticCode().show();//hahahaha \n show run
    }
}

如果一个类中的函数都是静态的,那么就不需要实例这个类了。为了防止任意实例化可以将构造函数设置为private

class ArrayTool{
    //该类中的方法都是静态的,所以该类是不需要创建对象的。为了保证不让其他程序创建该类对象
    //可以将构造函数私有化。
    private ArrayTool(){}    

    public static int getMax(int[] arr){

    }
    public static selectSort(int[] arr){
        
    }
}

创建文档注释

javadoc

七、单例设计模式

单例模式可以保证一个类在内存中的对象唯一性。

如何保证对象的唯一性呢?

1、不允许其他程序用new创建该类对象。
2、在该类创建一个本类实例。
3、对外提供一个方法让其他程序可以获取该对象

具体步骤

1、私有化该类的构造函数。
2、通过new在本类中创建一个本类对象。
3、定义一个公有的方法,将创建的对象返回。

示例代码---饿汉式

class Single{
    //第一步
    private Single(){}

    //第二步
    private static Single s = new Single();

    //第三步
    public static Single getInstance(){
        return s;
    }

}

class SingleDemo{
    public static void main(String[] arg){
        Single s1 = Single.getInstance();//直接使用类名调用静态方法
        Single s1 = Single.getInstance();//直接使用类名调用静态方法


        //校验一下是不是一个对象
        System.out.println(s1==s2);//true
    }
}

单例设计模式内存图解

单例模式的另一种表现形式---懒汉式

class Single2{
    private Single2(){}

    private static Single2 s = null;

    public static Single2 getInstance(){
        if(s==null){
            s = new Single2();
        }
        return s;
    }
}