当前位置: 首页 > 图灵资讯 > 技术篇> 30天入门 Java:JavaSE基础阶段Day10~

30天入门 Java:JavaSE基础阶段Day10~

来源:图灵教育
时间:2023-06-07 09:35:24

今日内容:封装与隐藏、构造器、关键词this、package

每日一考1. 重载的方法是什么?

在同一类中,定义了相同的方法名,但不同的参数数/参数类型构成重载的方法。

2.说明Java方法中参数传输机制的具体体现?

对于基本数据类型,实参传递给形参的是数据值;

对于引用的数据类型,实参传递给形参的是地址值。(含变量的数据类型)

Person p1 = new Person();

User u1 = p1;//编译错误

3.成员变量和局部变量在声明位置、默认初始化值、有权修改符号修改和内存分配位置上有什么区别?

1)声明的位置:成员变量直接声明在类的一对大括号内;局部变脸声明在定义方法的小括号或方法体内。

2)是否有默认初始化值:成员变量有;局部变量需要显式赋值。

3)能否有权限修饰符修饰:成员变量可以由权限修饰符修饰;局部变量不能。

4)内存分配位置:成员变量在堆叠空间中分配内存;局部变量在堆叠空间中分配内存。

局部变量:方法内部、方法形参、构造器内部、构造器形参、代码块内

4.谈谈return关键词的使用

return对于具有返回值的方法,return对于没有返回值的方法,return表示该方法已经结束。

5.提供以下代码的内存分析

如下图

复习

  1. 匿名对象

创建的对象没有明确赋予变量名,即匿名对象

特点:匿名对象只能调用一次

应用场景:当一种方法的参数类型为class时,new作为该方法的实际参考引入新对象;由于匿名对象只能使用一次,new对象只能在该方法中使用。

  1. 方法的重载

“两同一不同”:相同的类别,相同的方法名;不同的参数列表(参数数字/参数类型)

注:严格按照定义判断两种方法是否重载,与方法的权限修饰符、返回值类型、形参变量名、方法体无关!

如何确定类中某种方法的调用:确定方法名称 -> 确定参数列表

面试题:方法重载和重写的区别?(经典老题)

没关系。。。。。。

throws\throw的区别,String\StringBuffer\Stringbuilder的区别,Collectioncollections的差异,final\finallyfinalize的区别

抽象与接口,wait()与sleep()的区别

  1. 可变数形参的方法

可变数形参 是JDK 5.0新内容

格式:数据类型 ... 变量名

如:show(String ... strs) 与 show(String[] strs) 等价 (不构成方法重载,不能同时存在)。

  1. 值传递机制 ☆

形参与实参:

当方法定义形状参数时,声明小括号中的参数

实参是在调用方法时实际传递给形参的数据

值传递机制:

当参数为基本数据类型时,实参赋予形参实际存储的数据值;

当参数为引用数据类型时,实参赋予形参实参存储数据的地址值。

补充-以下代码的输出结果如下:

public class ValueTransferTest {public static void main(String[] args) {String s1 = "hello";

ValueTransferTest test = new ValueTransferTest();test.change(s1);System.out.println(s1);}public void change(String s){s = "hi~~";}

}String是引用数据类型的类别,但当声明String类型的变量时,不需要newString类别,可以直接写成String s1 = "hello";

并且"hello“以char[5]的形式存储在字符串常量池中,而不是堆叠空间,并将字符串数组的第一个地址值赋予变量s1;

调用change()方法时,将实参s1作为形参s传输给s赋值hi~~”字符串数组“hi第一个地址值赋予变量s,变量s1的值仍然是字符串数组“hello第一个地址值。方法调用后,变量s出栈,输出变量s1的值,为“hello”。

1、面向对象的特征1:包装和隐藏

  1. 问题的引入

1)当我们创建一个类别的对象时,我们可以通过“对象。属性”来赋值对象的属性。

2)在这里,赋值操作应受到属性数据类型和存储范围的限制。此外,没有其他限制。

3)但在实际问题中,在赋值属性时,需要增加额外的限制。这种限制不能反映在属性声明中。

4)限制条件只能通过方法添加。

5)同时,用户需要避免再次使用“对象.属性”赋值属性(将属性声明为私有) private)

此时,封装性反映在属性上

  1. 包装的体现

私有化类属性(private),同时,提供公共服务(public)的方法来 获取 和 设置 这个属性的值。

封装性:

①属性私有化 ②不对外暴露的私有方法 ③在单例模式中,构造器的私有化 ...

3.封装和权限修饰符

1)Java规定的四种权限:

从小到大排序: private < 缺省 < protected < public

2)4种权限可用于修改 类 及 类的内部结构 :属性、方法、结构器、内部类别。具体:

修饰:只有缺省,public

修饰内部结构:private、缺省、protected、public都可以

  1. 总结

Java提供了四种权限修饰符,以反映调用时类和类的内部结构的可见性大小

1)私有属性不能在类外部调用:

2)私有方法不能在类外部(同一包内)调用

3)缺省 属性/方法 在 同一工程的不同包之间不能调用:

  1. 练习

创建程序,定义两类:Person和PersonTest。定义如下:

使用setage()设置人的合法年龄(0~130),使用setage()返回人的年龄。 在 PersonTest 类 中实例化 Person 类的对象 b , 调 用 setAge() 以及getage()方法,体验Java的包装。

1)在com.atguigu.在excer包中新建Person类:

package com.atguigu.excer;

public class Person {

private int age;public void setAge(int i){if(i < 0 || i > 130){// throw new RuntimeException(非法传入数据!");System.out.println(非法传入数据!");return;}age = i;  // 不符合上述条件(合法引入值)}public int getAge(){return age;}

}2)在com.atguigu.在excer包中新建一个Persontest类:

package com.atguigu.excer;

public class PersonTest {public static void main(String[] args) {

Person b = new Person();b.setAge(35);int age = b.getAge();System.out.println("age: " + age);}

}

二、三类成员:构造器1。构造器的作用

1)创建对象

2)初始化对象的信息

2.说明

1)如果没有显示定义结构,系统默认提供空参结构

2)定义结构器的格式:

权限修饰符 类名(形参列表){}

3)一个类中定义的多个结构器相互构成重载

4)一旦定义了类别的结构,系统将不再提供默认的空参结构

5)一个类中至少有一个结构器

  1. 练习

1)在前面定义的Person类中添加结构器,并使用结构器设置所有人的age 性初始值为18。

2)修改上述问题的中类和构造器,增加name属性,使每次创建person对象的相同性 初始化对象的age属性值和name属性值。

3)写两个类别,TriAngle和TriAngleTest,其中,Triangle类声明私有底边长base和高height,并声明公共方法访问私有变量。此外,还提供必要的类结构。这些公共方法用于计算三角形的面积。

TriAngle的定义:

public class TriAngle {private double base;private double height;

public TriAngle(){}public TriAngle(double b, double h){base = b;    // 底边长height = h;  // 高}public void setBase(double bse){base = bse;}public double getBase(){return base;}public void setHeight(double ht){height = ht;}public double getHeight(){return height;}// 计算三角形面积public double triArea(){return base * height / 2;}

}TriAngleTest类别:

public class TriAngleTest {public static void main(String[] args) {TriAngle t = new TriAngle(3, 4);

System.out.println(三角形的底边长为:" + t.getBase());System.out.println(三角形的高度为:" + t.getHeight());System.out.println(三角形的面积为:" + t.triArea());}

}注:一般提供空参的结构器

4.总结:属性赋值过程:

1)赋值位置:

① 默认初始化

② 显式初始化

③ 构造中的初始化

④ 通过“对象、属性”或“对象、方法”赋值

2)赋值顺序:

① - ② - ③ - ④

只有默认初始化值:

显示赋值时:

使用结构器赋值时:

使用“对象.方法”或“对象.属性”赋值时:

3)注意:

①、②、③只执行一次,④任何次数都可以执行

三、使用this关键词

  1. this可用于修改:属性、方法、结构器
  2. this修饰属性及方法:

理解为this 当前对象 或 目前正在创建的对象

2.1 在类的方法中

> 我们可以用“我们可以用”this.属性”或“this.方法”调用 当前对象 属性或方法;

> 通常选择省略“通常选择省略”this.”

> 特殊情况(方法形参和类属性重名),必须显示使用“this.变量的方法表明变量是属性而不是形参

该方法的形参和类属性重名2.2 在类结构器中

>我们可以用“我们可以用”this.属性”或“this.方法”调用 目前正在创建的对象 属性或方法;

>通常选择省略“通常选择省略”this.”

>特殊情况(方法形参和类属性重名),必须显示使用“this.变量的方法表明变量是属性而不是形参

  1. 调用结构器的this

① 可显示在类结构器中 “this(形参列表) 方式,调用 本类中 指定的 其他构造器

② 在结构器中,不能通过“this(形参列表)以自己的方式调用

③ 如果一个类中有n个结构器,最多使用n-1个结构器 “this(形参列表)

④ 规定:“this(形参列表) 在构造器的第一行必须声明

⑤ 最多只能声明一个构造器的内部 “this(形参列表) 调用其它结构器

该类别的结构器可以调用该类别的其他结构器4. 练习

添加必要的结构器,综合应用结构器的重载,this关键词。

1)创建Boy类,关键代码

2)创建Girl类,关键代码

3)创建BoyGirltest类,测试运行结果

四、两个实验实验1:Account_Customer

要求:

1)写一个名字 Account 类模拟账户。该类的属性和方法如下图所示。该类包含的属性:帐户 id,余额 balance,年利率 annualInterestRate;包含方法:访问器方法(getter 和 setter方法),取款方法 withdraw(),存款方式 deposit()。

public class Account {private int id; // 账号private double balance; // 余额private double annualInterestRate; // 年利率

public Account() {}public Account(int id, double balance, double annualInterestRate) {this.id = id;this.balance = balance;this.annualInterestRate = annualInterestRate;}public int getId() {return id;}public void setId(int id) {this.id = id;}public double getBalance() {return balance;}public void setBalance(double balance) {this.balance = balance;}public double getAnnualInterestRate() {return annualInterestRate;}public void setAnnualInterestRate(double annualInterestRate) {this.annualInterestRate = annualInterestRate;}// publiciccicic提款方法 void withdraw (double amount){if(balance < amount){System.out.println(用户余额<提款数额,取款失败!");}else{this.balance -= amount;System.out.println(“成功取款” + amount + "元,“用户余额为:” + this.balance);}}// publiciccc存款方法 void deposit (double amount){this.balance += amount;System.out.println(“成功存入” + amount + "元,“用户余额为:” + this.balance);}

}2)创建 Customer 类。

public class Customer {private String firstName;private String lastName;private Account account;

public Customer() {}public Customer(String f,String l){this.firstName = f;this.lastName = l;}public String getFirstName(){return firstName;}public String getLastName(){return lastName;}public void setAccount(Account account){this.account = account;}public Account getAccount(){return this.account;}

}3)写一个测试程序。

创建一个 Customer ,名字叫 Jane Smith, 他有一个账号 1000,余额为 2000 元, 年利率为 1.23% 的账户。

对 Jane Smith 操作。存入 100 元,再取出 960 元。再取出 2000 元。打印出 Jane Smith 基本信息。

public class Test {public static void main(String[] args) {Customer cus = new Customer("Jane", "Smith");Account acc = new Account(1000, 2000, 0.0123);cus.setAccount(acc);

// 存入 100 元,再取出 960 元。再取出 2000 元。cus.getAccount().deposit(100);cus.getAccount().withdraw(960);cus.getAccount().withdraw(2000);// 打印出 Jane Smith System的基本信息.out.println("Customer [" + cus.getLastName() + ", " + cus.getFirstName() + "] has an account: id is "+ cus.getAccount().getId() + ", annualInterestRate is " + cus.getAccount().getAnnualInterestRate() * 100 +"%, balance is " + cus.getAccount().getBalance());}

}

实验2:Account_Customer_Bank

要求:

1)按以下要求 UML 创建相应的类别,并提供必要的结构

在提款方法 withdraw()如果没有,需要判断用户余额是否能满足提款金额的要求, 应给出提示。deposit()方法表示存款。

public class Account {private double balance;

public Account(double init_balance){this.balance = init_balance;  // 账户的初始余额}public double getBalance(){return balance;}// 存款public void deposit(double amt){if(amt > 0){balance += amt;System.out.println(成功存款);}}// 取款public void withdraw(double amt){if(amt > balance){System.out.println(”取款失败!");}else{balance -= amt;System.out.println(“成功取款” + amt + "元");}}

}2)按以下要求 UML 创建相应的类别,并提供必要的结构

public class Customer {private String firstName;private String lastName;private Account account; // 请注意,account属性是account类型,使用次属性需要neww

public Customer(){}public Customer(String f, String l){this.firstName = f;this.lastName = l;}public String getFirstName(){return firstName;}public String getLastName(){return lastName;}public Account getAccount(){return account;}public void setAccount(Account acct){this.account = acct;}

}3)按以下要求 UML 创建相应的类别,并提供必要的结构

addCustomer 该方法必须根据参数(姓名、姓名)构建新的方法 Customer 对象,然后把 它放到 customer 在数组中。还必须把 numberOfCustomer 属性的值加 1。

getNumOfCustomers 方法返回 numberofCustomers 属性值。

getCustomer 方法返回和给出 index 与参数相关的客户。

public class Bank {private Customer[] customers; // 存储多个客户的数组private int numberOfCustomer; // 记录客户数量

public Bank(){// 声明一个长度为10的Customer类型的数组,用户存储客户数据customers = new Customer[10];}// 添加客户publiciccc添加客户 void addCustomer(String f, String l){Customer cus = new Customer(f, l);if(numberOfCustomer < customers.length){

//customers[numberOfCustomer] = cus;//numberOfCustomer ++;// 或者customersss[numberOfCustomer ++] = cus;}else{System.out.println(添加用户失败!);}}

// publicc获取客户数量 int getNumOfCustomer(){return this.numberOfCustomer;}// 在指定位置获取客户public Customer getCustomer(int index){

//return customers[index];// 可能出现的问题:1)数组未初始化 2)指针越界,也就是说,index值大于等于数组长度 3)index的值大于实际客户// 更严谨的写法:if(index >= 0 && index < numberOfCustomer){return customers[index];}return null;}}4)创建 BankTest 类,进行测试。

public class BankTest {public static void main(String[] args) {// 创建BankBankBank bank = new Bank();

// 添加客户1bank.addCustomer("Jane", "Smith");// 客户1 添加帐户bank.getCustomer(0).setAccount(new Account(2000));// 客户1账户操作bank.getCustomer(0).getAccount().withdraw(500);   // 取款500// 查看客户1余额doublele balance = bank.getCustomer(0).getAccount().getBalance();System.out.println("客户" + bank.getCustomer(0).getFirstName() + “账户余额为:” + balance);System.out.println(**********************);// 添加客户2bank.addCustomer("Lily", "Yang");bank.getCustomer(1).setAccount(new Account(1000));System.out.println(”银行客户数量为:" + bank.getNumOfCustomer());// 添加多个客户,输出账户信息String[] firstName = new String[]{"Alice", "Brown", "Cindy"};String[] lastName = new String[]{"Green", "White", "Black"};for(int i = 0; i < 3; i++){bank.addCustomer(firstName[i], lastName[i]);bank.getCustomer(i + 2).setAccount(new Account(1000));}System.out.println("客户\t\t余额”;for(int i=0; i<bank.getNumOfCustomer(); i++){System.out.println(bank.getCustomer(i).getFirstName() + " " + bank.getCustomer(i).getLastName() +"\t\t" + bank.getCustomer(i).getAccount().getBalance());}}

}输出结果:

五、关键字package、使用import1.关键字package

1)为更好地实现项目中级管理,提供包装概念

2)使用package声明 类 或 接口 在源文件首行声明所属包

3)包,属于标识符,遵循标识符的命名规则和规范(xxxyyyzzz),“见名知义”

4)包名中的 “.” 表示一层文件目录

补充:同一个包下,不能同名命名 类 或 接口

不同的包下,不能命名同名 类 或 接口

2.import 使用关键词

1)在源文件中显示的使用 import 导入指定包下的类别和接口

2)import结构声明 包与类的声明之间

3)如果需要导入多个结构,可以并列写出来

4)可以使用 “xxx.*导入xxx包下的所有结构的方法

5)如果使用的类别或接口是java.lang包下的定义可以省略import结构(r如String、System)

6)如果当前package定义了使用的类别或接口,则可以省略import结构

7)如果在源文件中使用不同包下的同名类,至少需要一个包 全类名 的方式显示

8)使用“xxx.*“xxx包下的所有类别或接口(不包括子包)都可以导入。如果使用xxx包下的子包中的结构,仍然需要显式导入

9)import static :导入指定 类或接口中 静态结构(不用于导入或接口):属性、方法 作者:naien https://www.tulingxueyuan.cn/d/file/p/20230607/xufw1g3jotg 出处:bilibili