上一讲末尾我们留下了两个问题:
(1)每次对象创建好后调用SetDate方法设置具体日期,比较麻烦,那对象该如何初始化?
(2)局部变量必须要初始化才能使用,为什么字段声明之后没有给值依然可以使用?
在这一讲我们将会为大家进行解答!!!
public class Date {
public int year;
public int month;
public int day;
public static void main(String[] args) {
//此处a没有初始化,编译时报错:
// Error:(24, 28) java: 可能尚未初始化变量a
// int a;
// System.out.println(a);
Date d = new Date();
System.out.println(d.year);
System.out.println(d.month);
System.out.println(d.day);
}
}
//输出
0
0
0对于成员变量来说,如果没有进行初始化,会有⼀个对应的默认值,默认值遵循如下规则:

在声明成员变量时,就直接给出初始值。
public class Date {
public int year = 1900;
public int month = 1;
public int day = 1;
public Date(){
}
public Date(int year, int month, int day) {
}
public static void main(String[] args) {
Date d1 = new Date(2021,6,9);
Date d2 = new Date();
}
}构造方法(也称为构造器)是⼀个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用⼀次。
public class Date {
public int year;
public int month;
public int day;
public Date(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
System.out.println("Date(int,int,int)⽅法被调⽤了");
}
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
// 此处创建了⼀个Date类型的对象,并没有显式调⽤构造⽅法
Date d = new Date(1999,6,9); // 输出Date(int,int,int)⽅法被调⽤了
d.printDate(); // 1999-6-9
}
}(1)名字必须与类名相同
(2)没有返回值类型,设置为void也不行
(3)创建对象时由编译器自动调用,并且在对象的生命周期内只调用⼀次(相当于⼈的出生,每个⼈只能出生⼀次)
(4)构造方法可以重载载(用户根据自己的需求提供不同参数的构造方法)
public class Date {
public int year;
public int month;
public int day;
// ⽆参构造⽅法
public Date(){
this.year = 1900;
this.month = 1;
this.day = 1;
}
// 带有三个参数的构造⽅法
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
Date d = new Date();
d.printDate();
}
}上述两个构造方法:名字相同,参数列表不同,因此构成了方法重载。
(5)如果用户没有显式定义,编译器会⽣成⼀份默认的构造方法,生成的默认构造方法⼀定是无参的。
public class Date {
public int year;
public int month;
public int day;
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
Date d = new Date();
d.printDate();
}
}上述Date类中,没有定义任何构造方法,编译器会默认生成⼀个不带参数的构造方法。
(6)⼀旦用户定义了其他的构造方法,编译器则不再生成。
public class Date {
public int year;
public int month;
public int day;
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
Date d = new Date();
d.printDate();
}
}上述代码运行之后会显示,没有无参构造方法。(啥构造方法都没有才会自动给无参数构造方法,只要有任何构造方法就不会给)
(7)构造方法中,可以通过this调用其他构造方法来简化代码
public class Date {
public int year;
public int month;
public int day;
public Date(){
this(1900, 1, 1);
}
// 带有三个参数的构造⽅法
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
}(this(...)必须是构造方法中第⼀条语句!!!)
( 不能形成环的调用!!!)
public Date(){
this(1900,1,1);
}
public Date(int year, int month, int day) {
this();
}(8)绝大多数情况下使用public来修饰,特殊场景下会被private修饰(后序讲单例模式时会遇到)
如果我们直接打印对象的引用,此时输出的结果为:类路径名@对象的hashcode值。
public class Person {
String name;
String gender;
int age;
public Person(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
public static void main(String[] args) {
Person person = new Person("Jim","男", 18);
System.out.println(person);
}
}如果想要默认打印对象中的属性该如何处理呢?答案:重写toString方法即可。
public class Person {
String name;
String gender;
int age;
public Person(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
@Override
public String toString() {
return "[" + name + "," + gender + "," + age + "]";
}
public static void main(String[] args) {
Person person = new Person("Jim","男", 18);
System.out.println(person);
}
}
// 输出结果:[Jim,男,18] 快捷键(重写toString):Alt + Ins(然后选择toString)
关于重写的理解,我们会在继承多态章节讲到。
(Package)是Java中⼀个组织类的⽅式,用于防止类名冲突和提⾼代码的可读性。包允许将类组织在⼀个层次结构中,类似于文件系统中的目录。
如,我们为了更好的管理学习过程当中的作业以及课设相关内容,分类将对应的文件放入到分类好的文件夹中,就是⼀种管理方式。

在Java中也引入了包,包是对类、接口等的封装机制的体现,是⼀种对类或者接口等的很好的组织方式。
Java 中已经提供了很多现成的类供我们使用.例如Date类:可以使用 java.util.Date 导⼊java.util 这个包中的 Date 类.
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
// 得到⼀个毫秒级别的时间戳
System.out.println(date.getTime());
}
}但是这种写法比较麻烦⼀些,可以使用import语句导入包.
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到⼀个毫秒级别的时间戳
}
}当然如果有很多java.util中的其他类,可以用import java.util.*,但是不建议用,忘记就可以(因为在不同的类中可能存在同名的包,产生冲突!!!)
可以使用importstatic导⼊包中静态的方法和字段。
import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
double x = 30;
double y = 40;
// 静态导⼊的⽅式写起来更⽅便⼀些.
// double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
double result = sqrt(pow(x, 2) + pow(y, 2));
System.out.println(result);
}
}(1)在文件的最上方加上⼀个package语句指定该代码在哪个包中.
(2)包名需要尽量指定成唯⼀的名字,通常会用公司的域名的颠倒形式(例如com.baidu.demo1 ).
(3)包名要和代码路径相匹配.例如创建com.baidu.demo1 的包,那么会存在⼀个对应的路径 com/baidu/demo1 来存储代码.
(4)如果⼀个类没有package语句,则该类被放到⼀个默认包中.
(1)在IDEA中先新建⼀个包:右键src->新建->包

(2)在弹出的对话框中输入包名,例如 com.baidu.demo1

#注:可能会有这样的显示,会不太好看

点击右上边齿轮,选第一个,把Flatten勾掉就好了


(3)在包中创建类,右键包名->新建->类,然后输⼊类名即可(在哪个包下面建类就会出现在那个下面)


(4)此时的代码中会出现package语句

(package packageName; 声明⼀个包)
(5)此时可以看到我们的磁盘上的目录结构已经被IDEA自动创建出来了

java.lang: 系统常⽤基础类(String、Object),此包从JDK1.1后⾃动导⼊。
java.lang.reflect:java 反射编程包;
java.net: 进⾏⽹络编程开发包。
java.sql: 进⾏数据库开发的⽀持包。
java.util: 是java提供的⼯具程序包。(集合类等) (重要)
java.io:I/O编程开发包。如果我们在定⼀个类的时候,如果没有指定成员变量/成员方法的访问权限,此时默认的访问权限就是包访问权限。
在com.bit.demo1定义Computer类,brand属性为默认权限【包访问权限】。
package com.bit.demo1;
public class Computer {
private String cpu; // cpu
private String memory; // 内存
public String screen; // 屏幕
String brand; // 品牌
public Computer(String brand, String cpu, String memory, String screen) {
this.brand = brand;
this.cpu = cpu;
this.memory = memory;
this.screen = screen;
}
public void Boot(){
System.out.println("开机~~~");
}
public void PowerOff(){
System.out.println("关机~~~");
}
public void SurfInternet(){
System.out.println("上⽹~~~");
}
}在com.bite.demo2中访问Computer 中的成员
package com.bite.demo2;
import com.bite.demo1.Computer;
public class TestComputer {
public static void main(String[] args) {
Computer p = new Computer("HW", "i7", "8G", "13*14");
System.out.println(p.screen);
// System.out.println(p.cpu); // 报错:cup是私有的,不允许被其他类访问
// System.out.println(p.brand); // 报错:brand是default,不允许被其他包中的类访问
}
}由于内容较多,会分为多篇解答,预知后续内容,请看后续博客!!!