Java基础——对象和类2(类的定义)

简介: Java基础——对象和类2(类的定义)

2 类的定义


2.1 编写一个类


在一个 Java 源文件中,可以定义多个类,但是只能定义一个公开类。


公开类的类名必须和文件名相同。

class Student{
}

2.2 定义类的属性

class Student{
    int age;
    String name;
}

实例变量和局部变量不同,局部变量必须先赋值后使用,而对于实例变量,系统会为其分配一个默认值。


实例变量的默认值规则与数组元素默认值一样,对于对象类型的属性,默认值为 null值,对于数值类型的属性,默认值为 0,而对于 boolean 类型属性,默认值为 false。


局部变量和实例变量命名冲突是允许的。


当实例变量和局部变量发生命名冲突时,以局部变量优先。


2.3 定义类的方法


2.3.1 方法声明和方法实现


方法声明分为五个部分:


      修饰符 返回值类型 方法名 参数表 抛出的异常


在方法声明之后,紧跟一个代码块,这个代码块称之为方法的实现。

class Student{#类
    int age;
    String name;#实例变量
    public void study(){#方法声明
        System.out.println(“Student study for 8 hours”);#方法实现
    }
}

2.3.2 方法的重载


在一个类中,我们可以定义一系列方法,这些方法的方法名相同,参数表不同,这种语法被称为“方法的重载”。

class Student{
    public void study(){
        System.out.println(“study()”);
    }
    public void study(int n){
        System.out.println(“study(int)”);
    }
}

上面这段代码中,在 Student 类中定义了两个 study 方法,一个无参,另一个带一个字符串参数。程序运行时,根据不同的参数,会调用不同的方法。

public class TestStudent{
    public static void main(String args[]){
        Student stu = new Student();
        stu.study(); //调用无参的 study 方法,打印 study()
        stu.study(10); //调用 int 参数的 study 方法,打印 study(int)
    }
}

当程序被编译时,如果出现方法的重载,Java 编译器会根据实参的类型,来匹配一个合适的方法调用。因此,方法的重载又被称为“编译时多态”。


2.4 构造方法


构造方法(也被翻译成构造器)是面向对象特有的概念,是一种比较特殊的方法。

class Student{
    public Student(){
        System.out.println(“Student()”);
    }
}

2.4.1 构造方法的基本概念


构造方法没有返回值类型


构造方法的方法名与类名相同


构造方法对方法名有要求,对参数表没有要求。因此,一个类中可以利用


方法重载,添加多个构造方法。

class Student{
    public Student(){
           System.out.println(“Student()”);
    }
    public Student(int n){
        System.out.println(“Student(int)”);
    }
}

构造方法不能手动调用,只能在对象创建时自动调用一次


构造方法由 JVM 来自动调用。在使用 new 关键字创建对象时,会自动调用对象的构造方法。

public class TestStudent{
    public static void main(String args[]){
    //创建一个 Student 对象,并在创建时调用无参构造方法
    Student stu1 = new Student();
    //创建一个 Student 对象,并在创建时调用有参构造方法
    Student stu2 = new Student(10);
    }
}

2.4.2 默认构造方法

class MyClass{
    int a;
    int b = 100;
}
    public class TestMyClass{
        public static void main(String args[]){
            MyClass mc = new MyClass();//编译正常
    }
}

在 Java 中,如果类中没有定义任何的构造方法,则编译器会自动生成一个公开的、无参的空构造方法。

class MyClass{
    int a;
    int b = 100;
    //增加一个有参构造方法,则编译器就不生成默认构造方法
public MyClass(int n){} 
 }
上述代码中,已经定义了一个有参的构造方法,则编译器不会添加默认无参的构造方法。
例如:
public class TestMyClass{
    public static void main(String args[]){
        MyClass mc = new MyClass();//!编译出错,找不到无参构造方法
    }
}

需要注意的是,如果一个类中明确的定义了任何一个构造方法,则编译器就不会自动生成默认构造方法。


2.4.3 对象创建的过程


创建一个对象,在不涉及继承(这是下一章的内容)的情况下,基本步骤为 3 步:


1. 分配空间


计算机中的对象,本质上是内存中的一块数据。因此,在计算机中创建一个对象,就意味着必须在内存中为一个对象分配一块数据区域。


此外,在分配空间的同时,会把对象所有的属性设为默认值。这也是为什么实例变量不用赋值,就有默认值的原因。


2. 初始化属性


如果我们在定义实例变量的同时,为实例变量进行了赋值。则赋值语句在这一步骤执行。


3. 调用构造方法


当分配空间和初始化属性完成之后,最后一步是对该对象调用构造方法。

class MyClass{
    int a;
    int b = 100;
    public MyClass(){
        a = 20;
        b = 30;
    }
}
public class TestMyClass{
    public static void main(String args[]){
        MyClass mc = new MyClass();
        System.out.println(mc.a);
        System.out.println(mc.b);
    }
}

分析上述 MyClass 对象创建的过程。首先,为对象分配空间。分配的空间中,有一块区域用来保存实例变量 a,有一块区域用来保存实例变量 b。这两块区域在分配完之后,获得默认值 0。如下图所示:


image.png


分配空间之后,属性被赋值为默认值。之后,执行初始化属性的步骤。由于 a 属性没有被直接赋值,因此初始化属性时仅需要为 b 赋值即可。之后,调用 MyClass 的无参构造方法。由于在构造方法内部为 a 属性和 b 属性赋值为 20 和 30,因此最后在程序中输出时,输出的是 20 和 30。


综上所述,对象的创建过程分为三步:分配空间、初始化属性、调用构造方法。其中,调用构造方法是对象创建中最后一个步骤。当构造方法完成之后,意味着对象的创建彻底完成了。


相关文章
|
1月前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
148 57
|
4天前
|
JSON Java Apache
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
|
1月前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
53 8
|
1月前
|
Java 编译器
Java重复定义变量详解
这段对话讨论了Java中变量作用域和重复定义的问题。学生提问为何不能重复定义变量导致编译错误,老师通过多个示例解释了编译器如何区分不同作用域内的变量,包括局部变量、成员变量和静态变量,并说明了使用`this`关键字和类名来区分变量的方法。最终,学生理解了编译器在逻辑层面检查变量定义的问题。
Java重复定义变量详解
|
1月前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
73 17
|
1月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
134 4
|
1月前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
76 2
|
1月前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。
58 4
|
1月前
|
Java
在Java中定义一个不做事且没有参数的构造方法的作用
Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误,因为Java程序在父类中找不到没有参数的构造方法可供执行。解决办法是在父类里加上一个不做事且没有参数的构造方法。