构造方法
构造器的定义、作用
构造方法的特征
它具有与类相同的名称;它不含返回值;
注意:在构造方法里不含返回值的概念是不同于“void”的,在定义构造方法时加了“void”,结果这个方法就不再被自动调了。
构造方法的作用
当一个类的实例对象刚产生时,这个类的构造方法就会被自动调用,我们可以在这个方法中加入要完成初始化工作的代码。这就好像我们规定每个“人”一出生就必须先洗澡,我们就可以在“人”的构造方法中加入完成“洗澡”的程序代码,于是每个“人”一出生就会自动完成“洗澡”,程序就不必再在每个人刚出生时一个一个地告诉他们要“洗澡”了。
构造器(构造方法)
功能:创建类的实例时,初始化实例的一组指令。
语法格式:
< 修饰符> <类名>([< 参数表>]) {
[< 语句>]
}
举例:
public class Animal {
private int legs;
public Animal() {legs = 4; } //构造器
public void setLegs(int i) {
legs = i;
}
public int getLegs(){return legs;}
}
创建Animal类的实例:Animal a=new Animal(); //调用构造器,将legs初始化为4
注释:构造器的名称必须与类名相同。修饰符:public、private、protected
构造器不是方法,没有返回值(连void也不能写)
默认的构造方法
Java语言中,每个类都至少有一个构造方法;
如果类的定义者没有显式的定义任何构造方法,系统将自动提供一个默认的构造方法:
默认构造方法没有参数
默认构造方法没有方法体
默认的构造方法:Animal(){}
所以:不编写构造方法就能用new Xxx()创建类的实例。
Java类中,一旦类的定义者显式定义了一个或多个构造方法,系统将不再提供默认的构造方法;
构造器的主要作用:利用构造器参数初始化对象的属性。
练习3
1. 在前面定义的Person类中添加构造方法,利用构造方法设置所有人的age属性初始值都为18。
2. 修改上题中类和构造方法,增加name属性,使得每次创建Person对象的同时初始化对象的age属性值和name属性值。
1 /** 2 * 使用 class 关键字定义了一个类: Person 3 */ 4 public class Person { 5 6 //定义类的属性: 类型 属性名 7 String name = "unknown"; 8 9 //类型 变量名 = 初始值 10 int age = -1; 11 12 //Java类中,一旦类的定义者显式定义了一个或多个构造方法,系统将不再提供默认的构造方法; 13 public Person(String personName, int personAge){ 14 System.out.println("洗澡..."); 15 16 name = personName; 17 age = personAge; 18 } 19 20 //定义类的方法 21 //带返回值的: 返回值类型 方法名(){ 有可能使用 return 返回具体的值 } 22 int getAge(){ 23 return age; 24 } 25 26 //没有返回值的方法: 也开始使用 return 标示方法结束 27 //return 标示方法结束, return 的后面不能再有其他语句. 28 void shout(){ 29 System.out.println("I am " + name); 30 return; 31 } 32 33 //带参数, 但没有返回值的方法 34 void hello(String personName){ 35 System.out.println("Hello: " + personName); 36 } 37 38 //带参数, 且有返回值的方法 39 int add(int i, int j){ 40 int result = i + j; 41 return result; 42 } 43 }
1 /** 2 * 测试类 3 * 4 */ 5 public class TestPerson { 6 public static void main(String[] args) { 7 8 //3. 匿名对象: 没有名字的对象. 9 new Person("A", 10).shout(); 10 11 //2. 创建一个 Person 对象 p2 12 Person p2 = new Person("B", 18); 13 p2.shout(); 14 p2.hello("Mike"); 15 16 int result2 = p2.add(1, 4); 17 System.out.println(result2); 18 int age2 = p2.getAge(); 19 System.out.println(age2); //10. 定义类时的初始值 20 21 //p1 和 p2 是 Person 的两个对象, 操作任何一个的(非静态的)成员变量, 并不会对另一个对象的属性产生影响. 22 p2.age = 100; 23 24 System.out.println(); 25 26 //1. 创建一个 Person 对象 p1 27 //使用 new 关键字创建一个对象. 28 Person p1 = new Person("C", 30); 29 30 //为对象的属性赋值, 使用 . 操作符 31 p1.age = 30; 32 p1.name = "Tom"; 33 34 //调动对象的方法, 使用 . 操作符 35 int result = p1.add(2, 5); 36 System.out.println(result); 37 38 int age = p1.getAge(); 39 System.out.println(age); //30. 在 31 行为 p1 的 age 赋的值 40 41 p1.hello("Jerry"); 42 p1.shout(); 43 } 44 }
分析对象创建过程内存状态的变化
this 关键字
每个成员方法内部,都有一个this引用变量,指向调用这个方法的对象,类中的成员方法与this之间的关系如图:
1 public class Boy { 2 3 private String name; 4 5 public Boy(String n){ 6 name = n; 7 } 8 9 public String getName() { 10 return name; 11 } 12 13 /** 14 * 和一个女孩进行表白, 并得到女孩的回复. 15 * @param girl 16 */ 17 public void marry(Girl girl){ 18 System.out.println("嫁给我吧: " + girl.getName()); 19 20 /** 21 * this: this 是对 "调用当前方法的那个-当前对象" 对象的引用. 22 * 当前对象: 当前方法所在的对象. 23 * 24 * this 的用途: 指代的是当前对象 25 * 1. 在一般的方法中可以通过 this 来引用当前对象的成员(方法、属性) 26 * 2. 通过 this() 调用重载的构造器. 需要注意的是, 通过此种方法调用重载的构造器的代码必须放在当前构造器的第一行. 27 * 28 * public Person(String n, int a, String s, String m){ 29 * this(n, a, s); 30 * major = m; 31 * } 32 * 33 */ 34 girl.shout(this); 35 } 36 }
1 public class Girl { 2 3 private String name; 4 5 public Girl(String n){ 6 name = n; 7 } 8 9 public String getName() { 10 return name; 11 } 12 13 public void shout(Boy boy){ 14 System.out.println("好吧, 嫁给你: " + boy.getName()); 15 } 16 }
1 public class TestThis { 2 public static void main(String[] args) { 3 4 Boy boy = new Boy("Tom"); 5 Girl girl = new Girl("Jerry"); 6 7 boy.marry(girl); 8 } 9 }
函数的参数传递
基本数据类型的参数传递
1 //package: package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包 2 package com.atguigu.app; 3 4 //import:为使用定义在不同包中的Java类,需用import语句来引入所需要的类。 5 //import语句告诉编译器到哪里去寻找类。 6 import java.io.File; 7 import java.text.DateFormat; 8 9 class PassValue{ 10 public static void main(String [] args){ 11 12 File file = null; 13 System.out.print(Math.PI); 14 15 int x = 5; 16 change(x); 17 System.out.println(x); 18 } 19 20 public static void change(int y){ 21 y = 3; 22 } 23 }
引用数据类型的参数传递
1 public class PassRef { 2 int x; 3 public static void main(String [] args) { 4 PassRef obj = new PassRef(); 5 obj.x = 5; 6 change(obj); 7 System.out.println(obj.x); 8 } 9 10 public static void change(PassRef obj) { 11 obj.x = 3; 12 } 13 }
1 public class PassRef1 { 2 3 int x; 4 public static void main(String [] args){ 5 PassRef obj = new PassRef(); 6 obj.x = 5; 7 change(obj); 8 System.out.println(obj.x); 9 } 10 11 public static void change(PassRef obj){ 12 obj = new PassRef(); 13 obj.x = 3; 14 } 15 }
package语句/import语句
package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包。(若缺省该语句,则指定为无名包)。它的格式为:
package <顶层包名>[.<子包名>]* ;
举例:packTest.java
package p1; //指定类Test属于包p1
public class Test {
public void display() {
System.out.println("in method display()");
}
}
包对应于文件系统的目录,package语句中,用‘ .’ 来指明包(目录)的层次;
包通常用小写单词,类名首字母通常大写。
为使用定义在不同包中的Java类,需用import语句来引入所需要的类。Import语句告诉编译器到哪里去寻找类。
语法格式:
import 包名[.子包名…]. <类名 |*>
应用举例:
import p1.Test; //import p1.*;表示引入p1包中的所有类
public class TestPackage{
public static void main(String args[]){
Test t = new Test(); //Test类在p1包中定义
t.display();
}
}
JDK中主要的包介绍
java.lang----包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能。
java.net----包含执行与网络相关的操作的类。
java.io----包含能提供多种输入/输出功能的类。
java.util----包含一些实用工具类,如定义系统特性、使用与日期日历相关的函数。