Java学习6-面向对象基础 成员变量、成员方法、构造方法、this关键字、静态字段、静态方法

一、面向对象概述

面向过程开发,其实就是面向着具体的每一个步骤和过程,把每一个步骤和过程完成,然后由这些功能方法相互调用,完成需求。
面向过程的代表语言:C语言

当需求单一,或者简单时,我们一步一步去操作没问题,并且效率也挺高。可随着需求的更改,功能的增多,发现需要面对每一个步骤很麻烦了,这时就开始思索,能不能把这些步骤和功能在进行封装,封装时根据不同的功能,进行不同的封装,功能类似的封装在一起。这样结构就清晰了很多。用的时候,找到对应的类就可以了。这就是面向对象的思想。

   

在用面向对象思想体现的时候,给出一个三句话使用规则,让我们更符合面向对象思想
    A:首先分析有那些类
    B:接着分析每个类应该有什么
    C:最后分析类与类的关系

 

类和对象的关系

类:是一组相关的属性和行为的集合
对象:是该类事物的具体体现
举例:
    类    学生
    对象    班长就是一个对象

Java中用class描述事物(自定义类):
    成员变量    就是事物的属性
    成员方法    就是事物的行为
定义类其实就是定义类的成员(成员变量和成员方法)

对象创建:Student s = new Student(); //调用构造方法

调用方式:对象名.属性;  对象名.方法名(参数列表);

 

二、继承、封装、多态概述

封装(把实现细节隐藏,提供公共的访问方法):

1. 将对象的属性和行为封装起来,其载体就是类,对客户隐藏类实现细节。

2. 采用封装的思想保证了类内部数据结构的完整性,应用该类的用户不能轻易的直接操作此数据结构,只能执行类允许公开的数据。

特点:

1. 类将内部数据隐藏

2. 为用户提供对象的属性和行为的接口

3.用户不能操作类中的内部数据。

私有只是封装的一种体现,隐藏才算是封装。

 

继承(子类继承父类的属性和方法,子类也可有自己的属性和方法):

1. 子类的实例都是父类的实例

2. 不能说父类的实例是子类的实例

 

多态:

多态的体现并不依赖具体类,而是依赖抽象类和接口。抽象类不能实例化对象。

 

三、成员变量、成员方法、构造方法、this关键字

1.成员变量

成员变量:定义时变量可为其赋值,也可不为其赋值。

Java中常见类型的默认值:

byte、short、int、long  默认值:0

float、double  默认值:0.0

char  默认值‘ ’

boolean  默认值:false

引用类型(如String)  默认值:null

成员变量与局部变量的区别:

  1. 作用域:成员变量作用于整个类,局部变量只作用于它所属的范围(函数、语句)

  2. 生命周期&位置:成员变量存储在堆内存中,是属于对象的,随着对象存在消失。局部变量存储在栈内存中,是属于他所属的范围的,使用完自动释放。

  3. 初始值:成员变量有默认初始值,局部变量没有默认值,必须先定义,再赋值,最后才能使用。

局部变量:成员方法内定义的变量

  1. 局部变量在方法被执行时创建,在方法执行结束时被销毁

  2. 局部变量在使用时必须进行赋值操作或被初始化,否则会出现编译错误。

  3. 如果一个方法中含有与成员变量同名的局部变量,则方法中对这个变量的访问以局部变量进行。

 

2.成员方法

[权限修饰符][返回值类型] 方法名([参数类型 参数名] ...){方法体  return 返回值;}

public static void main(String[] args){... }

成员方法的参数:

1. 值参数:表明实参和形参之间按值传递

  在方法中对值类型的形参的修改并不会影响实参。

  实参:传给方法的值

  形参:方法内部接收实参的变量 

  基本类型参数的传递,是调用方值的复制。双方各自的后续修改,互不影响。

2. 引用参数

  在给方法传递参数时,参数的类型是数组、字符串、或是其它引用类型,那么在方法中对参数的修改会反映到原有的数据或是其它引用类型上,这种类型的方法参数,称之为引用类型。

  引用类型参数的传递,调用方的变量,和接收方的参数变量,指向的是同一个对象。双方任意一方对这个对象的修改,都会影响对方。

3. 不定长参数

  权限修饰符 返回值类型 方法名(参数类型...参数名)

  如:int add(int ... x){   }

  不定长参数必须是方法中的最后一个参数。

class Group {
    private String[] names;

    public void setNames(String... names) {
        this.names = names;
    }
}
//调用
Group g = new Group();
g.setNames("Xiao Ming", "Xiao Hong", "Xiao Jun"); // 传入3个String
g.setNames("Xiao Ming", "Xiao Hong"); // 传入2个String
g.setNames("Xiao Ming"); // 传入1个String
g.setNames(); // 传入0个String
//可变参数可以保证无法传入null,因为传入0个参数时,接收到的实际值是一个空数组而不是null

成员方法的使用:对象名.方法名(参数列表);

public class Main {
    public static void main(String[] args) {
        Person ming = new Person();
        ming.setName("Xiao Ming"); // 设置name
        ming.setAge(12); // 设置age
        System.out.println(ming.getName() + ", " + ming.getAge());
    }
}

class Person {
    private String name;
    private int age;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return this.age;
    }

    public void setAge(int age) {
        if (age < 0 || age > 100) {
            throw new IllegalArgumentException("invalid age value");
        }
        this.age = age;
    }
}

 

3. 构造方法

每当类实例化一个对象时,类就会自动调用构造方法。(创建对象)

特点:

  1. 无返回值类型

  2. 名称与类名相同

  3. 主要作用:完成对象的初始化工作,能把定义对象的参数传给对象成员。

如:public Book(){ }

注意:

  1. 构造方法中可以为成员变量赋值。没有在构造方法中初始化字段时,引用类型的字段默认是null,数值类型的字段用默认值,int类型默认值是0,布尔类型默认值是false

  2. 不过类中没有明确定义构造方法,则编译器会自动创建一个无参的默认构造方法

  3. 如果类中定义的构造方法都是有参构造方法,则编译器不会再自动为类生成一个默认的无参构造方法。当试图调用无参构造方法实例化对象时,编译器会报错。

  4. 只有类中无定义任何构造方法,编译器才会自动创建一个无参的默认构造方法。

  5. 构造方法还可以用private修饰,此时无法使用new 创建对象,需要使用静态方法生成类的对象。(类名.方法名调用,返回为new 对象)

  6. 私有构造方法-单例模式,即同一类创建的所有对象都是同一个实例。

构造方法和成员方法的区别:

  1. 格式区别:构造方法(方法名与类名相同,没有返回类型),成员方法(函数的定义格式)

  2. 用途:构造方法(用于创建对象并初始化),成员方法(完成一个功能)

  3. 什么时候调用:构造方法(new对象时被调用),成员方法(通过对象.方法名调用,实现某个功能)

 

4. this关键字

代表本类对象的引用。

当类中的成员变量与成员方法中的参数重名时,this关键字被隐式的用于引用对象的成员变量和方法。

this还可作为方法的返回值。

this还可用于调用类中的构造方法。this(1); 此时this语句前不能有其他代码。

class Person {
    private String name;

    public void setName(String name) {
        this.name = name; // 前面的this不可少,少了就变成局部变量name了
    }
}
class Person {
    private String name;
    private int age;

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

    public Person(String name) {
        this(name, 18); // 调用另一个构造方法Person(String, int)
    }

    public Person() {
        this("Unnamed"); // 调用另一个构造方法Person(String)
    }
}

 

四、静态字段、静态方法

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

  • 静态字段属于所有实例“共享”的字段,实际上是属于class的字段;

  • 调用静态方法不需要实例,无法访问this,但可以访问静态字段和其他静态方法;

  • 静态方法常用于工具类和辅助方法。

1. 静态变量

例:static public int water =0;

用类名.静态类成员调用

注意:同一个类的不同实例对象,共享同一静态变量。如果一个类将其更新,另一个类静态变量也会更改。

静态成员只能访问静态成员,静态方法中不能有this、super关键字。(静态成员优先于对象存在)

静态类中只有静态成员,非静态类中可以包含静态成员。

当类被首次加载时,静态变量就会被分配到内存中,直到程序结束才会释放。

 

2. 静态常量

例:final static double PI = 3.1415926;

通过final static修改,静态常量命名全部大写。

通过类名.静态常量名调用。

接口的静态字段:

因为interface是一个纯抽象类,所以它不能定义实例字段。但是,interface是可以有静态字段的,并且静态字段必须为final类型:

public interface Person {
    public static final int MALE = 1;
    public static final int FEMALE = 2;
}

因为interface的字段只能是public static final类型,所以我们可以把这些修饰符都去掉,上述代码可以简写为:

public interface Person {
    // 编译器会自动加上public statc final:
    int MALE = 1;
    int FEMALE = 2;
}

 

3. 静态方法

例: static public void show(){ }

静态方法只能被重载,不能被重写,因为它不属于类的实例成员。

通过类名.静态方法() 调用,无需创建对象。

因为静态方法属于class而不属于实例,因此,静态方法内部,无法访问this变量,也无法访问实例字段,它只能访问静态字段

 

4. 静态代码块

例: public class Test{

  static{  }

}

静态代码块随着类的加载而执行,只执行一次,优先于主方法。

  1. 静态代码块在类声明时运行,只运行一次

  2. 非静态代码块,每次创建对象的时候,会在构造方法之前运行

  3. 构造方法只有在使用new创建对象时才运行

  4. 成员方法只有在对象调用时才运行

 

五、对象的创建和销毁

对象的创建:使用new操作符调用构造方法创建对象

对象被创建出来时,就是一个对象的引用。

引用只是存放一个对象的内存地址,并非存放一个对象。

这个引用在内存中为对象分配了存储空间。

对象的销毁:

Java拥有一套完整的垃圾回收机制。

垃圾:1. 对象引用超过其作用范围,这个对象将被视为垃圾。

  2. 将对象赋值为null

注意:垃圾回收器只能回收那些由new操作符创建的对象。

如果某些对象不是通过new操作符在内存中获取一块内存区域,这些对象可能不能被垃圾回收机制所识别,所以提供了finalize()

 

finalize() : Object类,声明为protected。用户可在类中自己定义该方法,垃圾回收时会先调用该方法,下一次垃圾回收时,才能真正回收被对象占用内存。

finalize()方法和垃圾回收不一定会发生,当JVM内存损耗殆尽时,不会执行。

System.gc()方法 强制启动垃圾回收器。

 

posted @ 2023-07-30 18:24  highlightyys  阅读(41)  评论(0编辑  收藏  举报