Day06
可变个数的形参
-
采用数组形参来定义方法
public static void test(int a ,String[] books);
可变个数形参来定义方法
public static void test(int a ,String…books); -
说明:
1.可变参数:方法参数部分指定类型的参数个数是多个
2.声明方式:方法名(参数的类型名… 参数名)
3.可变形参的使用与方法参数部分使用数组是一致的
4.方法的形参部分有可变形参,需要放在形参的最后
5.使用可变形参的方法与同名的方法之间构成重载
package practice1;
/**
* 用数组的方式声明可变参数形参,以及可变参数形参
* @author MCC
*
*/
public class Day06Test {
public static void main(String[] args) {
// 调用数组形式
// new Day06Test().showInfo("xxx","yyy","zzz");
String[] str = new String[] {"xxx","yyy","zzz"};
new Day06Test().showInfo(str);
// 调用可变参数形式
new Day06Test().printInfo("xxx","yyy","zzz");
}
// 数组形式
public void showInfo(String[] str) {
for(int i = 0; i < str.length; i++) {
System.out.println(str[i]);
}
}
// 可变参数形参
public void printInfo(String... str) {
for(int i = 0; i < str.length; i++) {
System.out.println(str[i]);
}
}
}
- 注意:
(1)用数组来定义可变参数方法时,如果在调用方法时没有要传入的参数,则要将参数数组定义为空或null;
(2)使用Java特有的方式定义可变参数方法时,若没有需要传入的参数,则可不填。
(3)- printInfo(String s, int i, String… str) – 正确
- printInfo(String s, String… str, int i) – 错误
- printInfo(String… str, String s, int i) – 错误
方法的参数传递
参数传递
-
方法,必须有其所在类或对象调用才有意义。
-
形参:方法声明时的参数
-
实参:方法调用时实际传给形参的参数值
-
Java的实参值如何传入方法呢?
Java里方法的参数传递方式只有一种:值传递,即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。
JVM内存模型
- 基本数据类型:值保存在栈中,变量名指向栈内地址;
- 引用数据类型:值保存在堆中,栈中存放对象实例在堆中的地址。
public class TestTransfer {
public static void swap(int i){
i = 6;
System.out.println("swap方法里,i的值是" + i);
}
public static void main(String[] args) {
int a = 0;
swap(a );
System.out.println("main方法里,变量a的值是" + a);
}
}
输出:i = 6,a = 0
传入swap()方法中的只是a的值,和a本身不发生关系。
包 – package
在Java中,包的概念类似于文件夹,为了解决文件太乱不好管理以及文件同名的问题。
-
关键字 — package
-
必须放在第一条语句, 指明该文件中定义的类所在的包。(若缺省该语句,则指定为无名包)。
-
格式:
package 顶层包名.子包名 ; -
包对应于文件系统的目录,package语句中,用 " . " 来指明包(目录)的层次; 包通常用小写单词。
-
包与包之间的访问参照封装与隐藏中的权限修饰符。
-
举例
有两个包:package1、package2,现在想在package2包下再建立一个包test,则需要在建包界面输入包名为 package2.test,代表test包是package2包的子包。
import语句
为使用定义在不同包中的Java类,需用import语句来引入指定包层次下所需要的类或全部类( .*)。
-
语法格式:
import 包名 . 类名 -
注意:
(1)假设packageA下有许多class文件和子文件夹packageB,则 import packageA.*; 导入的是packageA中的全部类,而不包括packageB下的类,import packageA.packageB.*; 才是导入packageB下的所有类。
(2)假设包A下有类ClassA,包B下也有类ClassA,当在B中的ClassA导入A中的ClassA时,会造成类的重名,这时要使用包名.类名 加以区分。即import导入包时,若会出现类重名,那么就不要使用import,使用类的全名加以调用。
import day06.test.Person;
Person p = new Person();
//上述方法等同于下面的写法
//day06.test.Person p = new Person();
Jar包
Jar包是Java提供的将Java文件或class文件压缩的一种方式,类似于压缩包。eclipse上导入jar包的方法查阅资料。
面向对象特征之一:封装和隐藏
为了避免使用者对类内定义的属性进行直接操作,将不需要对外提供的内容都隐藏起来,包括属性的私有化(但不限于私有化)等。
- Java中通过将数据声明为私有的(private),再提供公共的(public)方法:getXxx()和setXxx()实现对该属性的操作,以实现下述目的:
(1)隐藏一个类中不需要对外提供的实现细节;
(2)使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作;
(3)便于修改,增强代码的可维护性。
四种访问权限修饰符
修饰符 | 类内部 | 同一个包 | 子类 | 其他 |
---|---|---|---|---|
private | √ | |||
(缺省) | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
- 说明:
(1)类只可以用public和default(缺省)修饰。
(2)private:只有在同一个类内才能被访问。
(3)缺省:在同一个包内的任何位置都可以被访问。
(4)protected:在同一个包内时,相当于public;在不同包内时,只有子类才能访问,且只能是子类对象(多态下的父类引用不能访问)。
(5)public:任何位置都能访问。
类的成员之三:构造器(构造方法)
-
构造器特征:
(1)它具有与类相同的名称。
(2)它不声明返回值类型(与声明为void不同)。
(3)不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值。 -
构造器的作用:
给对象进行初始化。
如:Order o = new Order(); Person p = new Person(Peter,15); -
语法格式:
修饰符 类名 (参数列表) {
初始化语句;
} -
构造器的分类:
隐式无参构造器(系统默认提供);
显式定义一个或多个构造器(无参、有参)。 -
注意:
(1)Java语言中,每个类都至少有一个构造器;
(2)默认构造器的修饰符与所属类的修饰符一致;
(3)一旦显式定义了构造器,则系统不再提供默认构造器;
(4)一个类可以创建多个重载的构造器;
(5)父类的构造器不可被子类继承。
构造器重载
构造器一般用来创建对象的同时初始化对象,构造器重载使得对象的创建更加灵活,方便创建各种不同的对象。
- 举例:
public class Person{
public Person(String name, int age, Date d) {this(name,age);…}
public Person(String name, int age) {…}
public Person(String name, Date d) {…}
public Person(){…}
}
public class Person {
private String name;
private int age;
private Date birthDate;
public Person(String name, int age, Date d) {
this.name = name;
this.age = age;
this.birthDate = d;
}
public Person(String name, int age) {
this(name, age, null);
//this.name=name; this.age=age; this.birthDate=null;
}
public Person(String name, Date d) {
this(name, 30, d);
//this.name=name; this.age=30; this.birthDate=d;
}
public Person(String name) {
this(name, 30); //this.name=name; this.age=30;
}
}
- 注意:
(1)构造器重载,参数列表必须不同(参数个数、参数顺序)。注意,一般方法的重载(参数个数、参数顺序、参数类型)不同则构成重载,构造器中的参数类型是固定的,不能不同。
(2)new实际上就是调用类的构造方法。
(3)构造方法前的修饰符要与类的权限修饰符一致, 类是public的,构造方法也应为public,类是缺省的,构造方法也应是缺省的。
this关键字
-
在方法内部使用,可以代表传入这个方法的对象。
-
在构造器内部使用,表示该构造器正在初始化的对象。
-
this表示当前对象,可以调用类的属性、方法和构造器。
-
什么时候使用this关键字呢?
当在方法内需要用到调用该方法的对象时,就用this。 -
举例:
class Person{ // 定义Person类
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ;
this.age = age ; }
public void getInfo(){
System.out.println("姓名:" + name) ;
this.speak();
}
public void speak(){
System.out.println(“年龄:” + this.age);
}
}
class Person{ // 定义Person类
private String name ;
private int age ;
public Person(){ // 无参构造
}
public Person(String name){
this(); // 调用本类中的无参构造方法
this.name = name ;
}
public Person(String name,int age){
this(name) ; // 调用有一个参数的构造方法
this.age = age;
}
public String getInfo(){
return "姓名:" + name + ",年龄:" + age ;
}
}
-
理解:
(1)当形参与成员变量重名时,如果在方法内部需要使用成员变量,必须添加this来表明该变量时类成员;
(2)在任意方法内,如果使用当前类的成员变量或成员方法可以在其前面添加this,增强程序的阅读性;
(3)this可以作为一个类中,构造器相互调用的特殊格式 -
注意:
(1)使用this()调用本类构造器时,必须放在构造器的首行;
(2)使用this()调用本类中其他构造器时,必须保证至少有一个构造器是不使用this的(要有个调用出口)。
JavaBean
JavaBean就是满足一定写法的Java程序。
-
JavaBean,是指符合如下标准的Java类:
(1)类是公共的;
(2)有一个无参的公共的构造器;
(3)有属性,属性一般是私有的,且有对应的get()、set()方法。 -
举例:
public class TestJavaBean{
private String name; //属性一般定义为private
private int age;
public TestJavaBean(){}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
练习
- 创建程序,在其中定义两个类:Person和TestPerson类。定义如下:
用setAge()设置人的合法年龄(0~130),用getAge()返回人的年龄。
在TestPerson类中实例化Person类的对象p,调用setAge()和getAge()方法,体会Java的封装性。
package practice2;
public class TestPerson {
public static void main(String[] args) {
Person p = new Person();
p.setAge(22);
System.out.println(p.getAge());
}
}
class Person {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if(age > 0 && age < 130) {
this.age = age;
}else {
System.out.println("The age that you set is ERROR!");
}
}
}
- 编写两个类,TriAngle和TestTriAngle,其中TriAngle中声明私有的底边长base和高height,同时声明公共方法访问私有变量;另一个类中使用这些公共方法,计算三角形的面积。
package practice1;
public class TestTriAngle {
public static void main(String[] args) {
TriAngle tri = new TriAngle();
tri.setBase(3.14);
tri.setHeight(2);
tri.count();
}
}
package practice1;
public class TriAngle {
private double base;
private double height;
public double getBase() {
return base;
}
public void setBase(double base) {
this.base = base;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public void count() {
System.out.println(0.5 * this.base * this.height);
}
}