深入浅出理解类和对象

阅读本文你将:

  1. 掌握类的定义方式以及对象的实例化
  2. 掌握类中的成员变量和方法的使用
  3. 掌握对象的整个初始化过程

类和对象

1.类和对象的初步认识

在谈类和对象之前,我们先来了解几个概念。

面向过程:注重的是过程,在整个过程中所涉及的行为,就是功能
面向对象:注重的是对象,也就是参与过程所涉及到的主体。是通过逻辑将一个个功能实现连接起来

C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
JAVA是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

举个洗衣服的栗子:
如果是面向过程:1.打开洗衣机 2.把洗衣液和衣服放进洗衣机 3.选择模式 4.启动洗衣机
如果是面向对象:我们只需要调用洗衣机这个对象即可完成,洗衣机具体是怎么实现洗衣服过程的我们不必关心。

因为从打开洗衣机到启动洗衣机的整个流程都是对洗衣机的操作,是洗衣机的行为。洗衣机就是一个对象,所以只要操作洗衣机所具备的功能,都要定义在洗衣机中。

面向对象的概念:

1.面向对象是思考问题的一种思考方式,是一种思想。比如:概念与实例。理论与实践。名和实等等。。
2.类就是一类对象的统称。对象就是这一类具体化的一个实例。
3.面向对象的好处:将复杂的事情变简单了,只要面对一个对象就行。

面向对象设计:

面向对象设计把握一个重要的经验:谁拥有数据,谁对外提供操作这些数据(私有)的方法! (被动的一方是数据的拥有者,主动的一方是执行者)
开发时:找对象,建对象,用对象,并维护对象之间的关系。
总之,面向对象就是用代码(类)来描述客观世界的事物的一种方式. 一个类主要包含一个事物的属性和行为

2.类和类的实例化

类就是一类对象的统称。对象就是这一类具体化的一个实例。

举个栗子:设计房屋的图纸就是一个类,通过图纸建造出来的房子就是一个对象,或者叫做一个实例。很显然一张图纸可以建造出多个房子,也就是说一个类可以实例化多个对象。

声明一个类就是创建一个新的数据类型,而类在java中属于引用类型,java使用关键字class来声明类。

基本语法

//创建类
class 类名 {
    
    
    field;//成员属性
    method;//成员方法
}
//实例化对象
类名 对象名 = new 类名();
class Person{
    
    

    public String name;//成员属性
    public int age;
    
    //成员方法
    public void eat(){
    
    
        System.out.println("就知道吃!");
    }
    public void sleep(){
    
    
        System.out.println("就知道睡!");
    }
}
public class TestDemo {
    
    
    public static void main(String[] args) {
    
    
        Person person = new Person();//new 实例化一个对象
        Person person1 = new Person();
        Person person2 = new Person();//可以实例化多个对象
        person.eat();//调用成员方法
        person.sleep();
        System.out.println(person.age);//调用成员属性
        System.out.println(person.name);
    }

}

注意事项:

  • new 关键字用于创建一个对象的实例.
  • 使用 . 来访问对象中的属性和方法.
  • 同一个类可以创建对个实例

3.类的成员

类的成员可以包含以下:字段(属性)、方法、代码块、内部类和接口等。此处我们重点介绍前三个。

3.1字段/属性/成员变量

字段也可以叫属性或成员变量,可以理解为一个类中的参数,比如一个Person 类,身高、年龄、性别、姓名这些都是人的基本数据信息,每个人都不一样;而成员方法则是人的一些功能或者说行为,比如每个人都会吃饭、睡觉等。

class Person{
    
    
    public String name;
    public int age;
    
}
public class TestDemo {
    
    
    public static void main(String[] args) {
    
    
        Person person = new Person();//new 实例化一个对象
        System.out.println(person.age);//调用成员属性
        System.out.println(person.name);
    }

}

输出结果:

0
null

这里需要注意的是,如果成员变量没有赋值,调用时会默认为初始值。

默认值规则:

  • 对于各种数字类型, 默认值为 0.
  • 对于 boolean 类型, 默认值为 false
  • 对于引用类型(String, Array, 以及自定制类), 默认值为 null

理解null

null 在 Java 中为 “空引用”, 表示不引用任何对象. 类似于 C 语言中的空指针. 如果对 null 进行 . 操作就会引发异常.

也可以定义成员属性时赋值,但不推荐。

class Person{
    
    
    public String name = "张三";
    public int age = 18;
    
}
public class TestDemo {
    
    
    public static void main(String[] args) {
    
    
        Person person = new Person();//new 实例化一个对象
        System.out.println(person.age);//调用成员属性
        System.out.println(person.name);
    }

}

输出结果:

18
张三

3.2 成员方法

前面说了,方法就是描述对象的行为

class Person{
    
    
   
    public void eat(){
    
    
        System.out.println(age+"岁的"+name+"就知道吃!");
    }
    public void sleep(){
    
    
        System.out.println(age+"岁的"+name+"就知道睡!");
    }
}
public class TestDemo {
    
    
    public static void main(String[] args) {
    
    
        Person person = new Person();
        person.name = "你";
        person.age = 18;
        person.eat();
        person.sleep();

    }

}

输出结果:

18岁的你就知道吃!
18岁的你就知道睡!

这样的 eat 和 sleep 方法是和 person 实例相关联的. 如果创建了其他实例, 那么 它们 的行为就会发生变化,除非你赋值都一样。

3.3 static 关键字

1、修饰属性
2、修饰方法
3、代码块
4、修饰类

a) 修饰属性
Java静态属性和类相关, 和具体的实例无关。换句话说, 同一个类的不同实例共用同一个静态属性。

class Person{
    
    
    public String name;
    public int age;
    public static int count;
}
public class TestDemo {
    
    
    public static void main(String[] args) {
    
    
        Person person = new Person();
        person.age++;
        System.out.println(person.age);
        Person.count++;
        System.out.println(person.count);
        System.out.println("===================");
        Person person1 = new Person();
        person1.age++;
        System.out.println(person1.age);
        Person.count++;
        System.out.println(person1.count);
    }
}

输出结果:

1
1
===================
1
2

我们可以看到,count 的值并不会因为新创建了对象而初始值变为0,而是原来的1。也就是说静态成员变量,和类相关,和具体的实例无关。所以我们是可以直接用类名访问的,而不需要创建一个对象。

public class TestDemo {
    
    
    public static void main(String[] args) {
    
    
        Person.count = 1;
        System.out.println(Person.count);
    }
}

输出结果:

1

b) 修饰方法
如果在任何方法上应用 static 关键字,此方法称为静态方法.

  • 静态方法属于类,而不属于类的对象。
  • 可以直接调用静态方法,而无需创建类的实例。
  • 静态方法可以访问静态数据成员,并可以更改静态数据成员的值
class Test{
    
    
    public int a ;
    public static int count;

    public static void change(){
    
    
        count = 100;
        //a = 100;静态方法里,不可定义非静态成员变量,否则会报错
    }
}
class Main{
    
    
    public static void main(String[] args) {
    
    
        Test.change();//用类名直接调用静态方法,不用创建实例
        System.out.println(Test.count);

    }
}

注意事项1:
静态方法和实例无关, 而是和类相关. 因此这导致了两个情况:

  • 静态方法不能直接使用非静态数据成员或调用非静态方法(非静态数据成员和方法都是和实例相关的).
  • this和super两个关键字不能在静态上下文中使用(this 是当前实例的引用, super是当前实例父类实例的引用, 也是和当前实例相关).
    注意事项2
  • 我们曾经写的方法为了简单, 都统一加上了 static. 但实际上一个方法具体要不要带 static, 都需要是情形而定.
  • main 方法为 static 方法.

为什么main 方法为 static 方法?

是因为main方法是Java解释器调用的,那时候还没有任何对象产生,没办法用对象调用,只能用类调用。不加的话,就好比你建了一栋房子,但是没有门,进不去里面。static就相当于那个门,加上程序才能往后面运行下去。

4. 封装

什么叫封装?
<<代码大全>> 开篇就在讨论一个问题: 软件开发的本质就是对程序复杂程度的管理. 如果一个软件代码复杂程
度太高, 那么就无法继续维护. 如何管理复杂程度? 封装就是最基本的方法.
在我们写代码的时候经常会涉及两种角色: 类的实现者类的调用者.
封装的本质就是让类的调用者不必太多的了解类的实现者是如何实现类的, 只要知道如何使用类就行了.
这样就降低了类使用者的学习和使用成本, 从而降低了复杂程度

4.1 private实现封装

private/ public 这两个关键字表示 “访问权限控制” 。
被 public 修饰的成员变量或者成员方法, 可以直接被类的调用者使用。
被 private 修饰的成员变量或者成员方法, 不能被类的调用者使用。

换句话说, 类的使用者根本不需要知道, 也不需要关注一个类都有哪些 private 的成员. 从而让类调用者以更低的 成本来使用类

我们可以将成员属性设置为private,而成员方法设置为public,这样就可以通过方法来修改属性值,就不用担心成员属性会被更改而引发的麻烦了。

注意事项

private 不光能修饰字段, 也能修饰方法 通常情况下我们会把字段设为 private 属性, 但是方法是否需要设为 public,
就需要视具体情形而定. 一般我们希 望一个类只提供 “必要的” public 方法, 而不应该是把所有的方法都无脑设为 public

4.2 getter和setter方法

class Person1{
    
    
    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 TestDemo1 {
    
    
    public static void main(String[] args) {
    
    
        Person1 person = new Person1();
        person.setAge(18);
        person.setName("wenan");
        System.out.println(person.getAge());
        System.out.println(person.getName());
    }
}

输出结果:

18
wenan

注意事项

  • getName 即为 getter 方法, 表示获取这个成员的值.
  • setName 即为 setter 方法, 表示设置这个成员的值
  • 当set方法的形参名字和类中的成员属性的名字一样的时候,如果不使用this, 相当于自赋值. this 表示当前实例的引用.
  • 不是所有的字段都一定要提供 setter / getter 方法, 而是要根据实际情况决定提供哪种方法.
  • 在 IDEA 中可以使用 alt + insert (或者 alt + F12) 快速生成 setter / getter 方法. 在VSCode 中可以使用鼠标右键菜单 -> 源代码操作 中自动生成 setter / getter 方法

5.构造方法

构造方法是一种特殊方法, 使用关键字new实例化新对象时会被自动调用, 用于完成初始化操作。

new 执行过程:

  • 为对象分配内存空间
  • 调用对象的构造方法

语法规则:

  • 方法名称必须与类名称相同
  • 构造方法没有返回值类型声明
  • 每一个类中一定至少存在一个构造方法(没有明确定义,则系统自动生成一个无参构造)
class Person1{
    
    
    private String name;
    private int age;

    public Person1(){
    
    
        System.out.println("不带参数的构造方法");
    }
    public Person1(String name){
    
    
        this.name = name;
        System.out.println("带1个参数的构造方法");
    }
    public Person1(String name,int age){
    
    
        this.name = name;
        this.age = age;
        System.out.println("带2个参数的构造方法");
    }
    public void show(){
    
    
        System.out.println("name: "+name+" age: "+age);
    }

}
public class TestDemo1 {
    
    
    public static void main(String[] args) {
    
    
        Person1 p1 = new Person1();//调用不带参数的构造函数 如果程序没有提供会调用不带参数的构造函数
        p1.show();
        Person1 p2 = new Person1("zhangfei",80);//调用带有2个参数的构造函数
        p2.show();
    }
}

输出结果:

不带参数的构造方法
name: null age: 0
带2个参数的构造方法
name: zhangfei age: 80

6. toString方法

我们刚刚注意到,我们在把对象的属性进行打印的时候,都自己实现了show函数,其实,我们大可不必。我们可以使用 toString 这样的方法来将对象自动转成字符串。

class Person1{
    
    
    private String name;
    private int age;

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

输出结果:

Person1{name=‘null’, age=0}

注意事项:

  • toString 方法会在 println 的时候被自动调用.
  • 将对象转成字符串这样的操作我们称为 序列化.
  • toString 是 Object 类提供的方法, 我们自己创建的 Person 类默认继承自 Object 类, 可以重写
    toString 方法实现我们自己版本的转换字符串方法.
  • @Override 在 Java 中称为 “注解”, 此处的 @Override 表示下面实现的 toString方法是重写了父类的方法.
  • IDEA快速生成Object的toString方法快捷键:alt+f12(insert)

7.匿名对象

  • 匿名只是表示没有名字的对象.
  • 没有引用的对象称为匿名对象.
  • 匿名对象只能在创建对象时使用.
  • 如果一个对象只是用一次, 后面不需要用了, 可以考虑使用匿名对象
class Person1{
    
    
    private String name;
    private int age;
    public Person1(String name,int age) {
    
    
        this.age = age;
        this.name = name;
    }
    public void show() {
    
    
        System.out.println("name:"+name+" " + "age:"+age);
    }

}
public class TestDemo1 {
    
    
    public static void main(String[] args) {
    
    
        new Person1("caocao",19).show();//通过匿名对象调用方法
    }
}

输出结果:

name:caocao age:19

本文结束,以上内容既是对你的分享,也是对我的总结。码字不易,如果可以,点个赞再走可好?

猜你喜欢

转载自blog.csdn.net/weixin_42907822/article/details/116046298