【JavaSE】类和对象

目录

一、面向过程和面向对象

二、类、类的实例化和对象

2.1 类和对象

2.2 static关键字

2.3  成员变量和成员方法

Question1:由类实例化对象,实例化的对象在哪存储呢?

Question2:可以在类中,对类的成员变量赋初值吗?

Question3:实例化对象后,怎样通过对象的引用访问对象的成员变量?

Question4:引用=null,代表什么意思?

Question5:普通成员变量和静态成员变量有什么区别呢?

Question5:普通成员方法和静态成员方法有什么区别呢?

Question6:在普通成员方法里面可以调用静态成员方法?

Question7:在静态成员方法里面可以调用普通成员方法?

2.4 总结

三、封装

3.1 为什么需要封装

3.2 如何封装以及封装后如何访问

Question1:get 和 set方法中的this是啥?

3.4 总结

四、构造方法

4.1 new的执行过程

4.2 构造方法

4.3 构造方法的特点

4.4 解密this(重点)

4.5 总结

五、代码块

5.1 普通代码块(用法较少)

5.2 构造代码块(实例代码块)

5.3 静态代码块

5.4 总结

六、匿名对象

七、toString方法

总结


一、面向过程和面向对象

在了解类和对象之前,我们需要先了解面向过程和面向对象这两种编程思想。

面向过程:注重的是过程,将解决事情的过程分为很多步骤,每一步都得参与。

面向对象:注重的是对象,将一件事情拆成不同的对象,依靠对象的互相交互解决这件事。面向对象的过程就是:找对象、创建对象、使用对象

以做饭为例:

面向过程:洗菜-择菜-炒菜

面向对象:抽象为自己和妈妈两个实体,第一步:妈妈我饿了,第二步:妈妈去做饭,至于妈妈是如何做饭的,这个过程是不用考虑的。

二、类、类的实例化和对象

2.1 类和对象

类:类是一类对象的统称。

对象:是类具体化的一个实例。对象是由类实例化得到的,使用的关键字是new

类相当于一个模板,通过类这个模板可以实例化无数个对象。

也可以把类认为是一个数据类型,类似于int这种,只不过这个数据类型是由我们自定义的。

class Person{
    public String name;                // 成员变量
    public int age;                    // 成员变量
    public void eat(){                 // 成员方法
        System.out.println("吃饭饭");
    }
    public void play(){                  // 成员方法
        System.out.println("玩儿");
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
        Person person1 = new Person();     // 实例化对象
        person1.name = "zhangsan";
        person1.age = 24;
        person1.eat();
        person1.play();
    }
}

2.2 static关键字

在了解类的组成之前,我们先对static关键字做一个简单的了解。static英文原意是指“静态的”,但是在Java中的含义,和“静态的”这个字面意思没有任何关系。

static在Java中是表示“类的”,static  修饰的成员变量称为“类成员”,static修饰的成员方法是指“类方法”。由于类在程序中只有一份,static修饰的成员变量和成员方法在类里面,因此也就只有一份。

2.3  成员变量和成员方法

类里面有成员变量和成员方法。成员变量用来描述类的属性,成员方法用来描述类的行为。

根据是否有static修饰,成员变量被分为普通成员变量和静态成员变量,成员方法分为普通成员方法和静态成员方法两种。

(接下来我打算以提问的形式来分享一些细节的知识点)

Question1:由类实例化对象,实例化的对象在哪存储呢?

 从图中可以看出:

同一个类可以实例化多个对象,如Person类就实例化person1和person2两个对象。

实例化后得到的对象存贮在堆上,person1和person2存储的是对象的地址。

Question2:可以在类中,对类的成员变量赋初值吗?

可以,但是一般不建议,因为类就是一个模板,没必要写死。如果你将String name = ”zhangsan“,实际上并不是所有的人都叫张三。

Question3:实例化对象后,怎样通过对象的引用访问对象的成员变量?

访问包含读和写。可以直接通过 . 来访问。具体使用见下面的代码。

可以通过 . 来访问对象的成员变量,并对成员变量赋初值。如果对象的成员变量没有被设置初始值,那么会被设置成一个默认的初值。

规则:

引用类型:默认值为null

各种数字类型:默认值为 0

boolean类型:默认值为false

Question4:引用=null,代表什么意思?

表示该引用不指向任何对象

Question5:普通成员变量和静态成员变量有什么区别呢?

普通成员变量静态成员变量(有static修饰)
访问方式需要先实例化一个对象,通过对象的引用才可以访问到通过类名访问
存储位置方法区

通过一道题来帮大家加深一下理解。

从图中也可以看出,a作为 普通成员变量,是通过对象的引用来访问的,如t1.a++;count作为静态成员变量,是直接通过类名来访问的,如TestDemo.count++。

Question5:普通成员方法和静态成员方法有什么区别呢?

普通成员方法静态成员方法(有static修饰)
访问方式需要先实例化一个对象,通过对象的引用才可以调用通过类名调用

注意:不能讨论方法的存储的位置。方法是不占内存的,调用方法时开辟栈帧就可。

Question6:在普通成员方法里面可以调用静态成员方法?

可以。因为调用静态成员方法依靠于类名,不依靠于对象。调用普通成员方法提供了一个对象,这个对象有没有都不会都不会产生影响。

Question7:在静态成员方法里面可以调用普通成员方法?

不可以。静态方法直接通过类名调用,没有对象,调用普通成员方法需要一个对象,所以没办法调用。

2.4 总结

普通成员变量通过对象调用,存储在堆上。

静态成员变量通过类名调用,存储在方法区上。

普通成员方法的调用依赖于对象,在其内部可以调用静态成员方法。

静态成员方法的调用依赖于类名,在其内部不能调用普通成员方法。

三、封装

3.1 为什么需要封装

在写代码时会涉及到两种角色,一种是类的实现者,一种是类的调用者。为了避免类的实现者改了类的成员变量后,类的调用者写的代码中也需要跟着改。因此,将类的成员变量使用private修饰,类的调用者就获取不到该成员变量,依据提供的public的访问方法来访问成员变量。(一般情况下,这个public的访问方法是不会修改的)

封装的本质是:让类的调用者不必过多了解类的实现者是如何实现类的,只需要知道是如何使用类就行了。这样就可以降低类使用者的学习和使用成本,从而降低了复杂程度。

3.2 如何封装以及封装后如何访问

使用private实现封装,封装后提供一个public的访问方法。可以再IDEA里面生成getter和setter方法,提高开发效率(右键--generate--getter and setter)。

class Person{
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
public class Main1{
    public static void main(String[] args) {
        Person person1 = new Person();
        person1.setAge(24);   
        person1.setName("zhangsan");  
        person1.getName();
        person1.getAge();
    }
}

Question1:get 和 set方法中的this是啥?

如果没有this:

this是指当前对象的引用,加上this.name 就是指当前引用指向的对象的name,而不是形参name。 

3.4 总结

使用private进行封装,提供一个public的访问方法。IDEA可以自动生成getter和setter方法。this是指当前对象的引用。

四、构造方法

4.1 new的执行过程

第一步:为对象分配内存空间

第二步:调用合适的构造方法。

4.2 构造方法

构造方法是一种特殊方法,构造函数的方法名和类名一样,没有返回值。使用关键字new实例化对象时会被自动调用,用于完成初始化操作。

4.3 构造方法的特点

①方法名和类名一样,没有返回值。

②构造方法有多个。

在没有定义任何的构造函数前,编译器会自动生成一个不带参数的构造方法。

④不同的构造函数之间构成了重载。重载的特点:方法名相同,参数列表不同,返回值不做要求。

4.4 解密this(重点)

this是指当前对象的引用。

因为this依赖于对象,static不依赖对象,直接通过类调用,所以,this在static方法里面不能使用。

this有三种用法:

this.成员变量

this.成员方法

this(参数):this调用其他的构造函数,必须放在第一行。

class Person{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public Person(String name) {
        this("zhangsan",11); // this调用下面的构造函数,必须写在第一行
        this.name = name;
        //this("zhangsan",11);  //如果没写在第一行,编译不通过
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
public class Main1{
    public static void main(String[] args) {
        Person person2 = new Person("zhangsan");  // 可以根据需要选择合适的构造函数
        Person person3 = new Person("lisi",24);
    }
}

4.5 总结

构造函数不止一个,在new对象时选择合适的构造函数完成对象的初始化操作。

编译器会提供一个不带参数的构造函数的前提是------当前类中没有提供任何的构造方法

this可以调用其他的构造函数,但是必须得写在第一行。

五、代码块

这些都是定义在方法外面,类里面

5.1 普通代码块(用法较少)

定义在方法中的代码块。

 public static void main(String[] args) {
        {
            int a = 10;
            System.out.println(a); //10
        }
        int a = 100;
        System.out.println(a); // 100
    }

5.2 构造代码块(实例代码块)

定义在类中的代码块,一般用于初始化成员变量。

class Person{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person(){
        System.out.println("我是构造函数哦");
    }
    {
        this.name = "zhangsan";
        this.age = 20;
        System.out.println("我是实例代码块哦");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Main1{
    public static void main(String[] args) {
        Person person1 = new Person();
        System.out.println(person1.toString());

    }
}

运行结果:

注意:实例代码块优于构造函数执行。

5.3 静态代码块

初始化静态的数据成员和需要提前准备的数据。

class Person{
    private String name;
    private int age;
    private static String sex;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person(){
        System.out.println("我是构造函数哦");
    }
    {
        this.name = "zhangsan";
        this.age = 20;
        System.out.println("我是实例代码块哦");
    }


    static {
        sex = "female";
        System.out.println("我是静态代码块哦");
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

public class Main1{
    public static void main(String[] args) {
        Person person1 = new Person();
        Person person2 = new Person();
        System.out.println(person1.toString());

    }
}

运行结果:

总结:在运行时,静态代码块先执行,但对于同一个类中,静态代码块只执行一次。

class Person{
    private String name;
    private int age;
    private static String sex;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person(){
        System.out.println("我是构造函数哦");
    }
    static {
        sex = "female";
        System.out.println("我是静态代码块1哦");
    }
    static {
        sex = "female";
        System.out.println("我是静态代码块2哦");
    }
}

public class Main1{
    public static void main(String[] args) {
        Person person1 = new Person();
        Person person2 = new Person();

    }
}

运行结果:

 总结:如果都是静态的或者实例的,执行的顺序和定义的顺序有关,谁在前先执行谁。

里面不能用this哦!!!

5.4 总结

运行顺序:

先执行静态代码块  再执行实例代码块 最后再执行方法。这里的执行顺序和写的顺序无关。

六、匿名对象

没有引用的对象称为匿名对象。匿名对象只能在创建对象时使用。

使用范围:如果一个对象只是使用一次,后面不需要用了,可以考虑使用匿名对象。

class Person{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

public class Main1{
    public static void main(String[] args) {
        System.out.println(new Person("zhangsan", 12).toString());
    }
}

七、toString方法

toString 方法会在 println 的时候被自动调用。
将对象转成字符串这样的操作我们称为 序列化.
toString 是 Object 类提供的方法, 我们自己创建的 Person 类默认继承自 Object 类, 可以重写 toString 方法实现我们自己版本的转换字符串方法. 
@Override 在 Java 中称为 "注解"

总结

1.类中有普通成员变量、静态成员变量、普通成员方法和静态成员方法。

2.普通成员变量和普通成员方法通过对象访问;静态成员变量和静态成员方法通过类名访问。

3.静态成员方法内部不能调用普通成员方法;普通成员方法内部可以调用静态成员方法。

4.Person person1 = new Person(),person1中存的是对象的引用,在栈上,实例化后的对象在堆上存储。person1中存储的是对象在堆上的地址。静态成员变量存储在方法区。

5.使用new实例化对象,使用private封装。

6.实例化一个对象分为两步,给对象分配内存空间,调用合适的构造方法。

7.构造方法有多个,如果在类中未定义任何构造方法,编译器会默认提供一个不带参数的构造方法。多个构造方法之间构成重载。

8.重载:方法名相同,参数列表不同,返回值不做要求。

9.this 是指当前对象的引用

10.执行顺序:静态代码块 优于 实例代码块 优于 普通方法(与定义的顺序无关)

11.对于同一个类来说,静态代码块只执行一次。

12.多个静态代码块/实例代码块,谁在前先执行谁。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘减减

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值