怒肝俩月,新鲜出炉史上最有趣的Java小白手册,第一版,每个 Java 初学者都应该收藏(8)

简介: 怒肝俩月,新鲜出炉史上最有趣的Java小白手册,第一版,每个 Java 初学者都应该收藏

七、Java 的类和对象


类和对象是 Java 中最基本的两个概念,可以说撑起了面向对象编程(OOP)的一片天。对象可以是现实中看得见的任何物体(一只特立独行的猪),也可以是想象中的任何虚拟物体(能七十二变的孙悟空),Java 通过类(class)来定义这些物体,有什么状态(通过字段,或者叫成员变量定义,比如说猪的颜色是纯色还是花色),有什么行为(通过方法定义,比如说猪会吃,会睡觉)。


来,让我来定义一个简单的类给你看看。


public class Pig {

   private String color;


   public void eat() {

       System.out.println("吃");

   }

}


默认情况下,每个 Java 类都会有一个空的构造方法,尽管它在源代码中是缺省的,但却可以通过反编译字节码看到它。


public class Pig {

   private String color;


   public Pig() {

   }


   public void eat() {

       System.out.println("吃");

   }

}


没错,就是多出来的那个 public Pig() {},参数是空的,方法体是空的。我们可以通过 new 关键字利用这个构造方法来创建一个对象,代码如下所示:


Pig pig = new Pig();


当然了,我们也可以主动添加带参的构造方法。


public class Pig {

   private String color;


   public Pig(String color) {

       this.color = color;

   }


   public void eat() {

       System.out.println("吃");

   }

}


这时候,再查看反编译后的字节码时,你会发现缺省的无参构造方法消失了——和源代码一模一样。


public class Pig {

   private String color;


   public Pig(String color) {

       this.color = color;

   }


   public void eat() {

       System.out.println("吃");

   }

}


这意味着无法通过 new Pig() 来创建对象了——编译器会提醒你追加参数。


image.png


比如说你将代码修改为 new Pig("纯白色"),或者添加无参的构造方法。


public class Pig {

   private String color;


   public Pig(String color) {

       this.color = color;

   }


   public Pig() {

   }


   public void eat() {

       System.out.println("吃");

   }

}



使用无参构造方法创建的对象状态默认值为 null(color 字符串为引用类型),如果是基本类型的话,默认值为对应基本类型的默认值,比如说 int 为 0,更详细的见下图。


image.png


(图片中有一处错误,boolean 的默认值为 false)


接下来,我们来创建多个 Pig 对象,它的颜色各不相同。


public class PigTest {

   public static void main(String[] args) {

       Pig pigNoColor = new Pig();

       Pig pigWhite = new Pig("纯白色");

       Pig pigBlack = new Pig("纯黑色");

   }

}



你看,我们创建了 3 个不同花色的 Pig 对象,全部来自于一个类,由此可见类的重要性,只需要定义一次,就可以多次使用。


那假如我想改变对象的状态呢?该怎么办?目前毫无办法,因为没有任何可以更改状态的方法,直接修改 color 是行不通的,因为它的访问权限修饰符是 private 的。


最好的办法就是为 Pig 类追加 getter/setter 方法,就像下面这样:


public String getColor() {

   return color;

}


public void setColor(String color) {

   this.color = color;

}



通过 setColor() 方法来修改,通过 getColor() 方法获取状态,它们的权限修饰符是 public 的。


Pig pigNoColor = new Pig();

pigNoColor.setColor("花色");

System.out.println(pigNoColor.getColor()); // 花色



为什么要这样设计呢?可以直接将 color 字段的访问权限修饰符换成是 public 的啊,不就和 getter/setter 一样的效果了吗?


因为有些情况,某些字段是不允许被随意修改的,它只有在对象创建的时候初始化一次,比如说猪的年龄,它只能每年长一岁(举个例子),没有月光宝盒让它变回去。


private int age;


public int getAge() {

   return age;

}


public void increaseAge() {

   this.age++;

}



你看,age 就没有 setter 方法,只有一个每年可以调用一次的 increaseAge() 方法和 getter 方法。如果把 age 的访问权限修饰符更改为 public,age 就完全失去控制了,可以随意将其重置为 0 或者负数。


访问权限修饰符对于 Java 来说,非常重要,目前共有四种:public、private、protected 和 default(缺省)。


一个类只能使用 public 或者 default 修饰,public 修饰的类你之前已经见到过了,现在我来定义一个缺省权限修饰符的类给你欣赏一下。


class Dog {

}



哈哈,其实也没啥可以欣赏的。缺省意味着这个类可以被同一个包下的其他类进行访问;而 public 意味着这个类可以被所有包下的类进行访问。


假如硬要通过 private 和 protected 来修饰类的话,编译器会生气的,它不同意。


image.png


private 可以用来修饰类的构造方法、字段和方法,只能被当前类进行访问。protected 也可以用来修饰类的构造方法、字段和方法,但它的权限范围更宽一些,可以被同一个包中的类进行访问,或者当前类的子类。


可以通过下面这张图来对比一下四个权限修饰符之间的差别:


image.png


同一个类中,不管是哪种权限修饰符,都可以访问;

同一个包下,private 修饰的无法访问;

子类可以访问 public 和 protected 修饰的;

public 修饰符面向世界,哈哈,可以被所有的地方访问到。


相关文章
|
8月前
|
设计模式 安全 Java
面向对象编程的精髓:Java设计模式 - 原型模式(Prototype)完全参考手册
【4月更文挑战第7天】原型模式是OOP中的创建型设计模式,用于通过复制现有实例创建新实例,尤其适用于创建成本高或依赖其他对象的情况。它包括Prototype接口、ConcretePrototype实现和Client客户端角色。优点是性能优化、避免子类化和动态增加产品族。实现包括定义原型接口、实现具体原型和客户端调用克隆方法。最佳实践涉及确保克隆正确性、选择深拷贝或浅拷贝及考虑线程安全。但需注意克隆方法管理、性能开销和循环引用等问题。在Java中,实现Cloneable接口和覆盖clone方法可实现原型模式。
92 4
|
8月前
|
网络协议 Java Maven
Java自救手册
Java自救手册
100 2
|
8月前
|
算法 Java
「译文」Java 垃圾收集参考手册(四):Serial GC
「译文」Java 垃圾收集参考手册(四):Serial GC
|
8月前
|
算法 Java PHP
「译文」Java 垃圾收集参考手册(一):垃圾收集简介
「译文」Java 垃圾收集参考手册(一):垃圾收集简介
|
7月前
|
Java 开发者
【技术成长日记】Java 线程的自我修养:从新手到大师的生命周期修炼手册!
【6月更文挑战第19天】Java线程之旅,从新手到大师的进阶之路:始于创建线程的懵懂,理解就绪与运行状态的成长,克服同步难题的进阶,至洞悉生命周期的精通。通过实例,展示线程的创建、运行与同步,展现技能的不断提升与升华。
43 2
|
8月前
|
Java 开发者
效率工具RunFlow完全手册之Java开发者篇
这篇手册面向Java开发者,介绍了如何使用QLExpress执行Java代码和进行方法验证。示例包括数学计算、读取系统环境变量及格式化输出。QLExpress提供运行时执行Java代码的功能,并支持QLExpress语法的脚本文件。
51 3
效率工具RunFlow完全手册之Java开发者篇
|
7月前
|
Java 数据安全/隐私保护
Java基础手册二(类和对象 对象创建和使用 面向对象封装性 构造方法与参数传递 this关键字 static关键字 继承 多态 方法覆盖 final关键字 访问控制权限修饰符)
Java基础手册二(类和对象 对象创建和使用 面向对象封装性 构造方法与参数传递 this关键字 static关键字 继承 多态 方法覆盖 final关键字 访问控制权限修饰符)
41 0
|
7月前
|
存储 Java
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
46 0
|
7月前
|
存储 自然语言处理 Java
Java IO流完全手册:字节流和字符流的常见应用场景分析!
【6月更文挑战第26天】Java IO流涵盖字节流和字符流,字节流用于二进制文件读写及网络通信,如图片和音频处理;字符流适用于文本文件操作,支持多语言编码,确保文本正确性。在处理数据时,根据内容类型选择合适的流至关重要。
99 0
|
8月前
|
算法 安全 Java
「译文」Java 垃圾收集参考手册(三):GC 算法基础篇
「译文」Java 垃圾收集参考手册(三):GC 算法基础篇