07.01_构造方法(Constructor) 概述和格式
- A:构造方法概述和作用
- 给对象的数据(属性)进行初始化
- B:格式特点
- 方法名和类名相同(大小写也要和类名一致)
- 没有返回值类型,连void也没有
- 没有具体的返回值return
- C:案例演示
class Demo1_Constructor {
public static void main(String[] args) {
Person p = new Person(); //在创建对象的时候,系统就帮我们调用了构造方法
//p.Person(); //会报错,构造方法不能等用对象调用
p.show();
}
}
class Person {
private String name;
private int age;
public Person() {
name = "张三";
age = 23;
//return; //构造方法也是有return语句的,格式是return;
}
public void show() {
System.out.println(name + "..." + age);
}
}
07.02_构造方法的重载及注意事项
-
A:案例演示
-
重载:方法名相同,与返回值类型无关(构造方法没有返回值),只看参数列表。
-
程序段
class Demo1_Constructor { public static void main(String[] args) { Person p1 = new Person(); //调用空参构造 p1.show(); System.out.println("-----------------"); Person p2 = new Person("张三",23); //调用有参构造,好处是可以对类里的成员变量进行动态赋值 p2.show(); } } class Person { private String name; private int age; public Person() { //空参构造 System.out.println("空参的构造"); } public Person(String name,int age) { //有参构造 this.name = name; this.age = age; System.out.println("有参的构造"); } public void show() { System.out.println(name + "..." + age); } }
-
-
B:注意事项
- 如果我们没有给出构造方法,系统将自动提供一个无参数构造方法。
- 如果我们给出了构造方法(包括有参和无参),系统将不再提供默认的无参数构造方法
- 注意:这个时候,如果我们还想使用无参数构造方法,就必须自己给出。建议永远自己给出无参数构造方法。
07.03_给成员变量赋值的两种方式的区别
- A:setXXX方法
- 修改属性值
- B:构造方法
- 给对象中的属性进行初始化
- C:案例演示
class Demo1_Constructor {
public static void main(String[] args) {
Person p1 = new Person("张三",23); //调用有参构造
p1 = new Person("张改名",23); //这种方式运行结果貌似是改名了,其实是将原对象变成垃圾,不推荐
System.out.println(p1.getName() + "..." + p1.getAge());
System.out.println("---------------------");
Person p2 = new Person(); //调用空参构造
p2.setName("李四");
p2.setAge(24);
p2.setName("李改名"); //这个才是真正的改名,没有重新创建对象
System.out.println(p2.getName() + "..." + p2.getAge());
}
}
/*
构造方法
就是对属性进行初始化
setXXX方法
修改属性值
总结
这两种方式,在开发中用setXXX更多一些,因为比较灵活
*/
class Person {
private String name;
private int age;
public Person() { //空参构造
}
public Person(String name,int age) { //有参构造
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
07.04_创建一个对象的步骤
07.05_长方形案例练习
class Test1_Rectangle {
public static void main(String[] args) {
Rectangle r = new Rectangle(10,20);
System.out.println(r.getLength());
System.out.println(r.getArea());
}
}
/*
需求:
定义一个长方形类,求周长和面积
分析:
成员变量:
宽width,高high
空参有参构造
成员方法
setXXX和getXXX
求周长:getLength()
求面积:getArea()
*/
class Rectangle {
private int width; //宽度
private int high; //高度
public Rectangle() {} //空参构造
public Rectangle(int width,int high) { //有参构造
this.width = width;
this.high = high;
}
public void setWidth(int width) { //设置宽度
this.width = width;
}
public int getWidth() { //获取宽度
return width;
}
public void setHigh(int high) { //设置高度
this.high = high;
}
public int getHigh() { //获取高度
return high;
}
public int getLength() { //获取周长
return 2 * (width + high);
}
public int getArea() { //获取面积
return width * high;
}
}
07.06_static关键字及内存图
- A:不加static关键字
class Demo1_Static {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "苍老师";
p1.country = "日本";
p1.speak();
Person p2 = new Person();
p2.name = "小泽老师";
p2.country = "日本";
p2.speak();
}
}
class Person {
String name; //姓名
String country; //国籍,不加static
public void speak() {
System.out.println(name + "..." + country);
}
}
- B:内存图
上图中,我们发现两个人的国籍都是日本,而在堆里要占两块内存,有点浪费内存,所以能不能把其单独存储到一块区域,这就要用到static关键字。
- C:带static关键字
class Demo1_Static {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "苍老师";
p1.country = "日本"; //国籍只要赋值一次,下面p2也可以用
p1.speak();
Person p2 = new Person();
p2.name = "小泽老师";;
p2.speak();
}
}
class Person {
String name; //姓名
static String country; //国籍,加上static
public void speak() {
System.out.println(name + "..." + country);
}
}
- D:内存图
从上图中,可以看到加了static关键字的变量是存储在方法区里的静态区的,并没有存在堆上。
07.07_static关键字特点
- A:特点
- a:随着类的加载而加载
- b:优先于对象存在
- c:被类的所有对象共享
- 举例:咱们班的学生应该共用同一个班级编号
- 其实这个特点也是在告诉我们什么时候使用静态?
- 如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
- 共性用静态,特性用非静态
- d:可以通过类名调用
- 其实它本身也可以通过对象名调用
- 推荐使用类名调用
- 静态修饰的内容一般我们称其为:与类相关的, 类成员。
- B:案例演示
class Demo1_Static {
public static void main(String[] args) {
/*Person p1 = new Person();
p1.name = "苍老师";
p1.country = "日本";
p1.speak();
Person p2 = new Person();
p2.name = "小泽老师";;
p2.speak();*/
//用类名调用,且不需要创建对象
//推荐使用类名调用,因为这样可以避免创建对象,节约内存
Person.country = "日本";
System.out.println(Person.country);
}
}
class Person {
String name; //姓名
static String country; //国籍,加上static
public void speak() {
System.out.println(name + "..." + country);
}
}
07.08_static的注意事项
-
A:注意事项
- a:在静态方法中是没有this关键字的
- 静态是随着类的加载而加载,this是随着对象的加载而存在。
- 静态比对象先存在。
- b:静态方法只能访问静态的成员变量和静态的成员方法
- 静态方法:
- 成员变量:只能访问静态变量
- 成员方法:只能访问静态成员方法
- 非静态方法:
- 成员变量:可以是静态的,也可以是非静态的
- 成员方法:可以是静态的成员方法,也可以是非静态的成员方法。
- 简单记:
- 静态只能访问静态
- 静态方法:
- a:在静态方法中是没有this关键字的
-
B:案例演示
class Demo1_Static {
public static void main(String[] args) {
Demo.print2();
}
}
class Demo {
int num1 = 10;
static int num2 = 20;
public void print1() { //非静态成员方法,既可以访问静态成员,也可以访问非静态成员
System.out.println(num1);
System.out.println(num2);
}
public static void print2() {
//System.out.println(num1); //静态成员方法不能访问类中的非静态成员
System.out.println(num2);
}
}
- C:总结
- 由于static关键字标识的成员是优先于对象而存在的,所以与对象有关系的都不能用。其中this以及非静态成员都与对象有关系,所以都不能用。
- 其实这就是一个进内存顺序不同而造成的问题。
07.09_静态变量与成员变量的区别
- 静态成员变量也叫类变量。成员变量也叫对象变量。
- A:所属不同
- 静态变量属于类,所以也称为类变量
- 成员变量属于对象,所以也称为实例变量(对象变量)
- B:内存中的位置不同
- 静态变量存储于方法区中的静态区
- 成员变量存储于堆内存
- C:内存出现时间不同
- 静态变量随着类的加载而加载,随着类的消失而消失
- 成员变量随着对象的创建而存在,随着对象的消失而消失
- D:调用不同
- 静态变量可以通过类名调用,也可以通过对象名调用
- 成员变量只能通过对象名调用
07.10_main方法格式的详细解释
class Demo1_Main {
public static void main(String[] args) {
/*
public : 被jvm调用,所以权限要足够大
static : 被jvm调用,不需要创建对象,直接类名,调用即可
void : 被jvm调用,不需要有任何类型的返回值
main : 只有这样写才能被jvm识别,main不是关键字
String[] args : 以前是用来接收键盘录入的(控制台录入),但现在不用了,现在用Scanner
*/
}
}
07.11_工具类中使用静态
- A:制作一个工具类
- ArrayTool
- 1.获取最大值
- 2.数组的遍历
- 3.数组的反转
- B:基本类实现
class ArrayTool {
//如果一个类中所有方法都是静态的,需要多做一步,私有构造方法
private ArrayTool() {};
//1.获取最大值
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 0;i <arr.length;i++) {
if (max < arr[i]) {
max = arr[i];
}
}
return max;
}
//2.数组的遍历
public static void print(int[] arr) {
for (int i = 0;i < arr.length;i++) {
System.out.print(arr[i] + " ");
}
}
//3.数组的反转
public static void revArray(int[] arr) {
for (int i = 0;i < arr.length / 2;i++) {
int temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
}
}
- C:测试类实现
class Demo1_ArrayTool {
public static void main(String[] args) {
int[] arr = {33,11,22,66,55,44};
ArrayTool.print(arr);
}
}
- D:说明的问题
- 当一个类中所有的成员方法都是静态方法时,要多加一步私有构造方法。这样做的目的是为了不让其他类创建本类对象,直接用类名调用即可。
07.12_说明书制作——文档注释
- A:对工具类加入文档注释
/**
这是一个数组工具类,里面封装了查找数组最大值,打印数组,数组反转的方法
@author daocaoren
@version v1.0
*/
public class ArrayTool { //制作说明书时,类的前面要加public
//如果一个类中所有方法都是静态的,需要多做一步,私有构造方法
/**
私有构造方法
*/
private ArrayTool() {};
//1.获取最大值
/**
这是获取数组中最大值的方法
@param arr 接收一个int类型的数组
@return 返回数组中的最大值
*/
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 0;i <arr.length;i++) {
if (max < arr[i]) {
max = arr[i];
}
}
return max;
}
//2.数组的遍历
/**
这是遍历数组的方法
@param arr 接收一个int类型的数组
*/
public static void print(int[] arr) {
for (int i = 0;i < arr.length;i++) {
System.out.print(arr[i] + " ");
}
}
//3.数组的反转
/**
这是数组反转的方法
@param arr 接收一个int类型的数组
*/
public static void revArray(int[] arr) {
for (int i = 0;i < arr.length / 2;i++) {
int temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
}
}
-
B:步骤
- 1.在ArrayTool.java文件路径下,打开cmd,然后键入 javadoc -d api -version -author ArrayTool.java
- 2.那么在ArrayTool.java文件路径下,就会有一个api文件夹,点开index.html文件就能看到说明书了。
-
C:注意事项:
- a:类的前面要加上public。否则在生成文档的时候会报错
) {
System.out.print(arr[i] + " ");
}
}
//3.数组的反转
/**
这是数组反转的方法
@param arr 接收一个int类型的数组
*/
public static void revArray(int[] arr) {
for (int i = 0;i < arr.length / 2;i++) {
int temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
}
} - a:类的前面要加上public。否则在生成文档的时候会报错
* B:步骤
* 1.在ArrayTool.java文件路径下,打开cmd,然后键入 javadoc -d api -version -author ArrayTool.java
* 2.那么在ArrayTool.java文件路径下,就会有一个api文件夹,点开index.html文件就能看到说明书了。
* C:注意事项:
* a:类的前面要加上public。否则在生成文档的时候会报错
* b:类中的私有成员是不会生成文档注释的,即时加了文档注释,那么在最后生成的说明书中也会被隐藏。