【一步一步了解Java系列】:类与对象的联系

简介: 【一步一步了解Java系列】:类与对象的联系

看到这句话的时候证明:此刻你我都在努力

加油陌生人 1.png

对象

Java中的对象是什么呢?显然不是我们现实生活中的对象。

emmm,在Java中有这么一句话,Java中任何东西皆可为对象,猫,狗,人,猴,洗衣机,手机,电脑,键盘等等。

Java中是一个面向对象的语言,对比C语言有什么不同呢?

我们举一个简单的例子,现在我们要用代码写出一个求阶乘的方法,C语言中叫函数,Java叫方法.。

C语言:C语言中会直接写出一个函数这个函数就是求阶乘的代码作为一个函数。

Java:首先他会先找一个对象,比如上方中是谁要求阶乘,比如要求阶乘的是学生,那么我们就要创建一个学生的对象,然后这个对象要干嘛,他要求阶乘,那么我们这时候就要给这个对象创建方法。这个方法就叫做:成员方法。

上面是一个简单的例子来简单展现C语言与Java的不同,当然可能有人就会问那我该怎么创建对象呢?

那么接下来登场的就是Java中的类。

类是用来描述一个对象的,对象是一个真正存在的实体。想要运用好类这个语法。我们就需要完成这么几个步骤:


  1. 根据事件找到对象。
  2. 对象存在着什么变量。
  3. 变量要完成什么事件。
  4. 根据这些创建成员变量和成员方法。

注意:我们一般建议一个文件建一个类。

那么接下来就通过举例来让大家更好的理解上面的知识点。

public class Dog {
    int age;
    String name;
    public static void eat(){
        System.out.println("吃狗粮");
    }
     public static void speak(){
        System.out.println("狗叫");
}
}


如上就是我定义的一个类,这个类是用来描述一只狗的。这里面的成员变量有,age年龄,还有名字name,然后还有两个成员变量,当然这个 对象还未进行实例化。那么什么叫实例化呢?

对象的实例化

对象的实例化就是由类生成对象的过程叫做实例化。那么具体的代码实现是怎么样的呢?

public class Dog {
    int age;
    String name;
    public static void eat(){
        System.out.println("吃狗粮");
    }
     public static void speak(){
        System.out.println("狗叫");

}

    public static void main(String[] args) {
        Dog dog=new Dog();
        dog.age=2;
        dog.name="旺财";
        dog.speak();
        dog.eat();
        System.out.println(dog.age);
        System.out.println(dog.name);

    }
}

在上面的代码中 Dog dog=new Dog(); //对象的实例化,这条代码就是对象实例化的代码。这就是我们常说的new一个对象。


对象实例化后我们就可以通过”.“,操作符对,对象中的成员变量和成员方法进行赋值或调用方法。

当然大家可能就会好奇,如果我不给对象的成员变量进行赋值那么他会输出什么?其实如果不进行赋值那么它会默认给各种类型的数据的对应的”0值“,什么叫做各自的0值呢?那么我们就可以看下图了。


注意:局部变量在使用前必须要初始化,而成员变量可以不初始化。


this关键字

为了更好的理解this关键字,我们先抛出一段代码。

public class Student {
    String name;

    public void setName(String a) {
        name = a;
    }


    public static void main(String[] args) {
        Student stu1=new Student();
        Student stu2=new Student();
        Student stu3=new Student();
        
        stu1.setName("小明");        
        stu2.setName("小李");        
        stu3.setName("小刚");        
    }
}


在上方代码中我们定义了一个Student类,然后里面的成员变量有名字,那么我们还定义了一个成员方法setName,然后我们在main方法中实例化了3个对象,然后我们调用了setName方法,给每个对象起个名字。

我们先看一下结果


结果也是我们所期盼的结果了。可是我们想象一下,在setName中我们里面的赋值语句中有这么一条语句name=a;那么编译器在三个对象调用方法时是如何分辨出给对应的name赋值呢?其实这就说明每个对象调用方法就会给其成员变量给赋值。那么如果我们把setName设置成这样呢?name=name;

public class Student {
    String name;

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


    public static void main(String[] args) {
        Student stu1=new Student();
        Student stu2=new Student();
        Student stu3=new Student();

        stu1.setName("小明");
        stu2.setName("小李");
        stu3.setName("小刚");


        System.out.println(stu1.name);
        System.out.println(stu2.name);
        System.out.println(stu3.name);
    }
}

我们看一下结果

很显然此时setName里并未给成员变量name赋到值,打印出null是因为String对应的0值为null。那我们如果要解决这个问题,我们就需要用到this关键字。

public void setName(String name) {

    this.name = name;
}


只要加上this后代码就会知道this.name指的是对象的name,单单一个name就是成员变量的name,这样就可以正确的赋值方法。那this的本质是什么呢?

其实这个this就是你所调用的对象。用代码表示的话就是:

public void setName(Student this,String name) {

    this.name = name;
}

这里的形参就会多加一个this。那么肯定就会有人问了,我也没给setName里传对象,没有实参的1传入啊?

其实这个传参编译器已经会自动帮我们传参,只不过都会省略掉了而已。


构造方法

在Java中,构造方法是一种特殊的方法,它用于在创建对象时初始化对象的状态。构造方法具有以下特点:


名称与类名相同:构造方法的名称必须与类名完全相同,包括大小写。

没有返回类型:构造方法没有返回值,即使是void也没有。

自动调用:当使用new关键字创建对象时,构造方法会自动被调用,用于初始化对象。

可以有多个:一个类可以有多个构造方法,只要它们的参数列表不同(参数的数量或类型不同)。

不能被继承:构造方法不会被继承,即子类不会继承父类的构造方法。

不能直接调用:不能通过对象调用构造方法,它们是在对象创建时自动调用的。

如果我们没有自己定义构造方法则Java中会自动给我们构造一个空的构造方法。这个构造方法会省略掉我们是看不见的,但是他确实存在。


下面是一个简单的Java类示例,其中包含了一个构造方法:

public class Person {
    private String name;
    private int age;

    // 构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 其他方法
    public void displayInfo() {
        System.out.println("Name: " + name + ", Age: " + age);
    }
}

// 使用构造方法创建对象
Person person = new Person("Alice", 30);
person.displayInfo();


在这个例子中,Person类有两个私有属性name和age。Person类有一个构造方法Person(String name, int age),它接受两个参数来初始化对象的状态。当创建一个新的Person对象时,必须提供这两个参数,并且构造方法会被自动调用来设置对象的初始状态。


this关键字可以在一个构造方法中调用其它构造方法,例如:

public class Dog {
    String name;
    public Dog(){
        System.out.println("调用了无参的构造的方法");
    }

    public Dog(String name){
        this();
        this.name=name;
        System.out.println("调用了有参的构造的方法");

    }

    public static void main(String[] args) {

        Dog dog=new Dog("旺财");
    }

}


如上:我们在调用有参的构造方法时,也会自动调用无参的构造方法,但要注意this()必须在当前构造方法的第一个语句,否则就会报错。

目录
打赏
0
3
4
0
19
分享
相关文章
Java中判断一个对象是否是空内容
在 Java 中,不同类型的对象其“空内容”的定义和判断方式各异。对于基本数据类型的包装类,空指对象引用为 null;字符串的空包括 null、长度为 0 或仅含空白字符,可通过 length() 和 trim() 判断;集合类通过 isEmpty() 方法检查是否无元素;数组的空则指引用为 null 或长度为 0。
JAVA泛型类的使用(二)
接上一篇继续介绍Java泛型的高级特性。3. **编译时类型检查**:尽管运行时发生类型擦除,编译器会在编译阶段进行严格类型检查,并允许通过`extends`关键字对类型参数进行约束,确保类型安全。4. **桥方法**:为保证多态性,编译器会生成桥方法以处理类型擦除带来的问题。5. **运行时获取泛型信息**:虽然泛型信息在运行时被擦除,但可通过反射机制部分恢复这些信息,例如使用`ParameterizedType`来获取泛型参数的实际类型。
JAVA泛型类的使用(一)
Java 泛型类是 JDK 5.0 引入的重要特性,提供编译时类型安全检测,增强代码可读性和可维护性。通过定义泛型类如 `Box<T>`,允许使用类型参数。其核心原理是类型擦除,即编译时将泛型类型替换为边界类型(通常是 Object),确保与旧版本兼容并优化性能。例如,`Box<T>` 编译后变为 `Box<Object>`,从而实现无缝交互和减少内存开销。
Java快速入门之类、对象、方法
本文简要介绍了Java快速入门中的类、对象和方法。首先,解释了类和对象的概念,类是对象的抽象,对象是类的具体实例。接着,阐述了类的定义和组成,包括属性和行为,并展示了如何创建和使用对象。然后,讨论了成员变量与局部变量的区别,强调了封装的重要性,通过`private`关键字隐藏数据并提供`get/set`方法访问。最后,介绍了构造方法的定义和重载,以及标准类的制作规范,帮助初学者理解如何构建完整的Java类。
|
25天前
|
Object取值转java对象
通过本文的介绍,我们了解了几种将 `Object`类型转换为Java对象的方法,包括强制类型转换、使用 `instanceof`检查类型和泛型方法等。此外,还探讨了在集合、反射和序列化等常见场景中的应用。掌握这些方法和技巧,有助于编写更健壮和类型安全的Java代码。
38 17
|
1月前
|
java代码优化:判断内聚到实体对象中和构造上下文对象传递参数
通过两个常见的java后端实例场景探讨代码优化,代码不是优化出来的,而是设计出来的,我们永远不可能有专门的时间去做代码优化,优化和设计在平时
32 15
|
3月前
|
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
201 58
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
104 8
Java对象一定分配在堆上吗?
本文探讨了Java对象的内存分配问题,重点介绍了JVM的逃逸分析技术及其优化策略。逃逸分析能判断对象是否会在作用域外被访问,从而决定对象是否需要分配到堆上。文章详细讲解了栈上分配、标量替换和同步消除三种优化策略,并通过示例代码说明了这些技术的应用场景。
Java对象一定分配在堆上吗?