201871010118-唐敬博《面向对象程序设计(Java)》第四周学习总结
博文正文开头格式:(2分)
项目 | 内容 | |
这个作业属于哪个课程 | https://www.cnblogs.com/nwnu-daizh/ | |
这个作业的要求在哪里 | https://www.cnblogs.com/nwnu-daizh/p/11552848.html | |
作业学习目标 |
|
随笔博文正文内容包括:
第一部分:总结第四章理论知识(20分)
一.类
1.类体
类使用类体来描述所抽象出的属性 行为,类声明后的一对大括号{ ....... }以及他们之间的内容称作类体
变量的声明:依赖存储属性的值(体现对象的属性)
方法的定义:方法可以对类中声明的变量进行操作即给出算法;
2.成员变量
成员变量类型:整型,浮点型,字符型,逻辑类型,引用类型:数组类型,对象,接口
成员变量的有效范围:成员变量在整个类内都有效;
3.对象:三个主要特性;对象的行为,对象的状态,对象标识
4.
5.类之间的关系:依赖,聚合,继承
二.构造方法:无返回类型,方法名与类同名默认构造方法:如果类内没有定义该类的构造方法;这默认生成默认的无参的构造方法;倘若类内有定义一个或者多个构造方法这系统不默认生成无参构造方法;
1.创建对象 格式:Class_Name Object_name
Class A;
new Class_Name:返回的是该类在堆区中开辟内存的引用;对象的引用在栈区中,对象的实体在堆区中;
2.使用对象 对象操作自身的变量:格式:对象.变量
对象操作自身的函数:格式:对象.函数名()
3.对象的引用和实体 Class A; Class B;
A a = new A();
A b=a;//注意b中存放着是a的值;b即为a的引用;
三. 用户自定义类
1.Employee类 :在源文件中,只能有一个public类,并且文件名与public类类名相同,但可以有任意数目的非公有类。
2.多个源文件的使用 :编译多个源文件的程序时,只需javac 含主方法的文件
即可,编译器会自动查找编译使用到的类。并且,若之前编译过,若java编译器发现Employee.java较之前Employee.class有更新,会再编译新版本。
3.剖析Employee类: 强烈建议将实例子域标记为private。private确保只有类自身的方法能访问该实例域。一般将方法标记为public。public意味任何类的任何方法都可调用本方法。
4.从构造器开始 :必须注意在所有方法中不要命名与实例域同名的变量,否则局部变量会屏蔽同名实例域。
隐式参数与显式参数 方法中,关键字this表示隐式参数。Java中,所有方法必须在类内部定义,但并不表示它们是内联方法,是否将某个方法设置为内联方法是Java虚拟机的任务。
5.封装的优点: 获得实例域的值,用get set 方法(域访问器方法/域更改器方法)好处:不要编写返回 引用可变对象 的访问器方法,要返回一个可变对象的引用,应首先对它进行克隆(clone方法)。
可以改变内部实现,除了该类的方法外,不影响其它代码。更改器方法内部可以写错误检查等语句。
6.基于类的访问权限 一个方法可以访问所属类的所有对象的私有数据,而不仅限于访问隐式参数的私有特性。
7.私有方法 :可以设置一些辅助方法为private的,并且由于不会被其他类调用,所以可以随时删去。
8.final实例域 : final修饰符修饰的实例域必须在构建对象时初始化,即确保在构造器执行之后这个实例域被赋值。一般用来修饰基本类型域、或不可变类的域,否则容易造成混淆。
四.静态域与静态方法
1.静态域与实例域: 类中带有static关键字的属于静态域。每个类只有一个静态域,静态域属于类。而每个对象对于所有的实例域都有自己的一份拷贝,即每个对象都有一个自己的实力域。
2.静态常量:(1)静态变量使用的较少,静态常量使用的较多,例如public static final double PI=3.1415926535..(2)
static 静态(3)final修饰的局部变量,一旦赋值,无法改变——常量。
(4)由于每个类的对象都可以对公有域进行修改,所以最好不要将域设计为public。但将final域设为public却没问题,因为它不允许被修改。
3.静态方法: 用static修饰的方法,只能通过类名调用。
使用的两个情景:1一个方法所有参数都是通过显式参数提供,即没有this参数。2一个方法只需要访问类的静态域。
4.静态工厂方法——除使用构造函数外另一种创建实例的方法。
- 定义:不通过 new,而是用一个静态方法来对外提供自身实例的方法,即为静态工厂方法(Static factory method)。
Fragment fragment = MyFragment.newIntance();
- 考虑使用静态工厂方法代替构造器
因为静态工厂方法有诸多优点,总的来说,能够增大类的提供者对自己所提供的类的控制力。
- 有名字
- 可以返回原类型的子类
- 可以有多个参数相同但名称不同的工厂方法
- 可以减少对外暴露的属性
5.main方法:(1)main方法是一个静态方法。在启动程序时还没有任何对象,静态的main方法将执行并创建程序需要的对象。
(2)在一个类中可以有一个main方法,是一个常用的单元测试的技巧
- (3)如果想要独立地测试Employee类,只需要执行
java Employee
;如果Employee类是一个更大型应用Application的一部分,就可以执行java Application
,Employee类的main方法将永远不会执行。
五.方法参数
Java语言中,方法参数的传递方式总是按值调用(包括当对象引用作为参数时,也是按值传递,拷贝一份对象引用),方法不能修改传递给它的任何参数变量的内容。
六.对象构造
1.重载:(1)方法的签名:要完整的描述一个方法,需要指出方法名、参数类型。(2)返回类型不是方法名的一部分,不能有两个方法名、参数类型相同却返回值不同的方法
2.默认域初始化:域与局部变量的主要不同点:如果没有初始化类中的域,域会被初始化为默认值。而方法中的局部变量必须明确地初始化。
3.初始化数据域方法二:显式域初始化,会在构造器之前执行:可以在域声明中赋值。
4.初始化数据域方法三:使用初始化块,会在构造器之前执行。
八.this关键字
1.在构造方法中使用this:this代表当前对象
2.在实例方法中使用this
this.成员变量 this.成员方法 class A{ int x; static int y; void f(){ this.x=100; A.y=10; }
注意:this不能出现在类方法中,这是因为类方法可以通过类名直接调用,这时可能还没有任何对象的创建诞生
七.包
1.包语句 package 包名
2.有包名的类的存储目录:package tom.jiafei
javac tom\jiafei\源文件
3.运行有包名的主类:
java tom.jiafei.主类名
java语言不允许用户程序使用java作为包名的一部分,例如java.bird是非法的包名(发生运行异常)
八.import this语句
1.引入类库中 的类
import java.util.*;//导入java.util包下的所有类
果不想引入包下的类,则直接带上包名使用 java.util.Date date=new java.util.Date();
2.引入自定义包中的类
import 包名.*;//导入该包下的所有类 .* 代表所有的类 .; 代表加载应用程序当前目录下的无名包类
this关键字 1.在构造方法中使用this:this代表当前对象 2.在实例方法中使用this
this.成员变量 this.成员方法 class A{ int x; static int y; void f(){ this.x=100; A.y=10; }
注意:this不能出现在类方法中,这是因为类方法可以通过类名直接调用,这时可能还没有任何对象的创建诞生
九.文档注释
Java中有3种书写注释的方式
// 行注释,从开始到本行结尾。
/* ... */ 长篇注释
/** ... */ 可生成文档的注释。
1、使用javadoc工具可以由源文件产生HTML文档。
2、javadoc抽取信息范围:包,公有类与接口,公有的和受保护的域,公有的和受保护的构造器及方法。
3、每个/**... */文档注释在标记之后紧跟着自由格式文本(free-form text),标记由@开始,如:@author或@param。
4、自由格式文本中可以使用HTML修饰符,例如:用于强调的<em> ... </em>、用于设置登宽“打字机”字体的<code> ... </code>、用于强调的<span>...</span>以及包含图像的<img...>等。
5、类注释:必须放在import语句之后、类定义之前。(没有必要在每一行的开始都用星号)。
6、方法注释:必须放在所述方法之前,除了通用标记外,还可以使用下面的标记:
·@param这个标记将对当前方法的参数部分添加一个条目。这个描述可以占据多行,并可以使用HTML标记。一个方法的所有@param标记必须放在一起。
·@return这个标记对当前方法的返回值进行描述。这个描述可以跨越多行,可以施工HTML标记。
·@throws这个标记描述方法可能抛出有的异常。
7、域注释:只需要对共有域(通常指的是静态常量)建立文档。
8、通用注释:下面的标记可以用在类文档的注释中:
·@author这个标记产生一个“author”(作者)条目。可以使用多个@author标记,每个@author标记对应一个作者。
·@version这个标记将产生一个“version”(版本)条目。这里的文本可以是对当前版本的任何描述。
此标记可以用在所有的文档注释中:·@since这个标记将产生一个“since”(始于)条目。
十.类设计技巧
1、一定要保证数据私有
2、一定要对数据初始化
3、不要再类中使用过多的基本类型
4、不是所有的域都需要独立的域访问器和域更改器
5、将职责过多的类进行分解
6、类名和方法名要能够体现它们的职责
7、优先使用不可变的类
第二部分:实验部分
实验名称:实验三 类与对象的定义及使用
1. 实验目的:
(1) 熟悉PTA平台线上测试环境;
(2) 理解用户自定义类的定义;
(3) 掌握对象的声明;
(4) 学会使用构造函数初始化对象;
(5) 使用类属性与方法的使用掌握使用;
(6) 掌握package和import语句的用途。
第二部分:实验部分
实验名称:实验三 类与对象的定义及使用
1. 实验目的:
(1) 熟悉PTA平台线上测试环境;
(2) 理解用户自定义类的定义;
(3) 掌握对象的声明;
(4) 学会使用构造函数初始化对象;
(5) 使用类属性与方法的使用掌握使用;
(6) 掌握package和import语句的用途。
3. 实验步骤与内容:
实验1 任务1(10分)
公民身份证号码按照GB11643—1999《公民身份证号码》国家标准编制,由18位数字组成:前6位为行政区划分代码,第7位至14位为出生日期码,第15位至17位为顺序码,第18位为校验码。从键盘输入1个身份证号,将身份证号的年月日抽取出来,按年-月-日格式输出。注意:输入使用Scanner类的nextLine()方法,以免出错。
输入样例: 34080019810819327X
输出样例: 1981-08-19
实验程序:
import java.util.Scanner;
public
class
Main {
public
static
void
main(String[] args) {
// TODO Auto-generated method stub
Scanner
in
=
new
Scanner(System.
in
);
System.
out
.println(
"please input your ID:"
);
String s1 =
in
.nextLine();
String s2,s3,s4;
s2 = s1.substring(6, 10);
s3 =s1.substring(10, 12);
s4 = s1.substring(12, 14);
System.
out
.println(s2+
"-"
+s3+
"-"
+s4);
}
}
运行结果:
实验1 任务2(25分)
studentfile.txt文件内容是某班同学的学号与姓名,利用此文件编制一个程序,将studentfile.txt文件的信息读入到内存,并提供两类查询功能:(1)输入姓名查询学号;(2)输入学号查询姓名。要求程序具有友好人机交互界面。
编程建议:
(1)从文件中读入学生信息,可以编写如下函数:
public static void StudentsFromFile(String fileName))
(2)输入姓名查找学生学号,可以编写如下函数:
public static String findStudent(String name)
(3)输入学号查找学生姓名,可以编写如下函数:
public static String findStudent(String ID)
程序代码:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public
class
Main {
// private static Student students[];
private
static
ArrayList<Student> list;
public
static
void
main(String[] args) {
list =
new
ArrayList<>();
Scanner
in
=
new
Scanner(System.
in
);
try
{
readFile(
"studentfile.txt"
);
System.
out
.println(
"请选择操作,1按姓名,2按学号,3退出"
);
int
i;
while
((i =
in
.nextInt()) != 3) {
switch
(i) {
case
1:
System.
out
.println(
"请输入姓名"
);
String name =
in
.next();
Student student = findStudentByName(name);
if
(student ==
null
) {
System.
out
.println(
"没找到"
);
}
else
{
System.
out
.println(student.toString());
}
System.
out
.println(
"请选择操作,1按姓名,2按学号,3退出"
);
break
;
case
2:
System.
out
.println(
"请输入学号"
);
String id =
in
.next();
Student student1 = findStudentById(id);
if
(student1 ==
null
) {
System.
out
.println(
"没找到"
);
}
else
{
System.
out
.println(student1.toString());
}
System.
out
.println(
"请选择操作,1按姓名,2按学号,3退出"
);
break
;
default
:
System.
out
.println(
"输入有误"
);
System.
out
.println(
"请选择操作,1按姓名,2按学号,3退出"
);
break
;
}
}
}
catch
(IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
finally
{
in
.close();
}
}
public
static
void
readFile(String path) throws IOException {
FileReader reader =
new
FileReader(path);
BufferedReader br =
new
BufferedReader(reader);
String result;
while
((result = br.readLine()) !=
null
) {
Student student =
new
Student();
student.setName(result.substring(13));
student.setID(result.substring(0,12));
list.add(student);
}
br.close();
}
public
static
Student findStudentByName(String name) {
for
(Student student : list) {
if
(student.getName().
equals
(name)) {
return
student;
}
}
return
null
;
}
public
static
Student findStudentById(String Id) {
for
(Student student : list) {
if
(student.getID().
equals
(Id)) {
return
student;
}
}
return
null
;
}
}
class
Student {
private
String name;
private
String ID;
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
public
String getID() {
return
ID;
}
public
void
setID(String iD) {
ID = iD;
}
@Override
public
String toString() {
// TODO 自动生成的方法存根
return
"姓名是:"
+ name +
"学号是:"
+ ID;
}
}
运行结果:
实验2 测试程序1(10分)
实验程序如下:
import java.time.*;
/**
* This program tests the Employee class.
* @version 1.13 2018-04-10
* @author Cay Horstmann
*/
public
class
EmployeeTest
{
public
static
void
main(String[] args)
{
// fill the staff array with three Employee objects
Employee[] staff =
new
Employee[3];
//构造Employee数组,并有三个雇员对象;
staff[0] =
new
Employee(
"Carl Cracker"
, 75000, 1987, 12, 15);
staff[1] =
new
Employee(
"Harry Hacker"
, 50000, 1989, 10, 1);
staff[2] =
new
Employee(
"Tony Tester"
, 40000, 1990, 3, 15);
// raise everyone's salary by 5%
for
(Employee e : staff)
e.raiseSalary(5);
//调用raiseSalary的方法提高雇员薪水15%;
// print out information about all Employee objects
for
(Employee e : staff)
System.
out
.println(
"name="
+ e.getName() +
",salary="
+ e.getSalary() +
",hireDay="
+ e.getHireDay());
//打印每个雇员的信息;
}
}
class
Employee
//定义Employee类;
{
private
String name;
private
double
salary;
private
LocalDate hireDay;
//类的实例域定义来存放的需要操作的数据;
public
Employee(String n,
double
s,
int
year,
int
month,
int
day)
{
name = n;
salary = s;
hireDay = LocalDate.of(year, month, day);
//根据参数设置日期,参数分别为年月日;
}
//构造Employee类的对象,并声明局部变量name,salary,hireday;
public
String getName()
{
return
name;
//取得name属性的值;
}
public
double
getSalary()
{
return
salary;
//取得salsry属性的值;
}
public
LocalDate getHireDay()
{
return
hireDay;
//取得hireday属性的值;
}
public
void
raiseSalary(
double
byPercent)
{
double
raise = salary * byPercent / 100;
salary += raise;
//调用方法的对象salary实例域设置为新值;
}
}
运行结果
实验2 测试程序2(5分)
程序如下:
/**
* This program demonstrates static methods.
* @version 1.02 2008-04-10
* @author Cay Horstmann
*/
public
class
StaticTest
{
public
static
void
main(String[] args)
{
// fill the staff array with three Employee objects
Employee[] staff =
new
Employee[
3
];
//构造了一个Employee数组,并填入了三个雇员对象
staff[
0
] =
new
Employee(
"Tom"
,
40000
);
staff[
1
] =
new
Employee(
"Dick"
,
60000
);
staff[
2
] =
new
Employee(
"Harry"
,
65000
);
// print out information about all Employee objects
for
(Employee e : staff)
{
e.setId();
System.out.println(
"name="
+ e.getName() +
",
+ e.getSalary());
////调用getName方法、getId方法以及getSalary方法将每个雇员的信息打印出来
}
int
n = Employee.getNextId();
// calls static method 通过类名调用这个方法,只需要访问类的静态域
System.out.println(
"Next available >//将其输出在控制台上
}
}
class
Employee
//Employee类
{
private
static
int
nextId =
1
;
//静态方法访问自身的静态域
private
String name;
//私有域
private
double
salary;
private
int
id;
public
Employee(String n,
double
s)
{
name = n;
salary = s;
id =
0
;
}
public
String getName()
{
return
name;
}
public
double
getSalary()
{
return
salary;
}
public
int
getId()
{
return
id;
}
public
void
setId()
{
id = nextId;
// set id to next available id
nextId++;
}
public
static
int
getNextId()
{
return
nextId;
// returns static field
}
public
static
void
main(String[] args)
// unit test
{
Employee e =
new
Employee(
"Harry"
,
50000
);
System.out.println(e.getName() +
" "
+ e.getSalary());
//输出在控制台上
}
}
运行结果如下:
|
实验2 测试程序3(5分)
实验程序如下:
/**
* This program demonstrates parameter passing in Java.
* @version 1.01 2018-04-10
* @author Cay Horstmann
*/
public
class
ParamTest
{
public
static
void
main(String[] args)
{
/*
* Test 1: Methods can't modify numeric parameters
*/
System.out.println(
"Testing tripleValue:"
);
double
percent =
10
;
//采用按值调用,然后再调用以下方法
System.out.println(
"Before: percent="
+ percent);
tripleValue(percent);
System.out.println(
"After: percent="
+ percent);
/*
* Test 2: Methods can change the state of object parameters
*/
System.out.println(
"\nTesting tripleSalary:"
);
Employee harry =
new
Employee(
"Harry"
,
50000
);
System.out.println(
"Before: salary="
+ harry.getSalary());
tripleSalary(harry);
System.out.println(
"After: salary="
+ harry.getSalary());
/*
* Test 3: Methods can't attach new objects to object parameters
*/
System.out.println(
"\nTesting swap:"
);
Employee a =
new
Employee(
"Alice"
,
70000
);
//按引用调用实现交换两个雇员对象状态的方法,但是并没改变存储在a和b中的对象引用
Employee b =
new
Employee(
"Bob"
,
60000
);
System.out.println(
"Before: a="
+ a.getName());
System.out.println(
"Before: b="
+ b.getName());
swap(a, b);
System.out.println(
"After: a="
+ a.getName());
System.out.println(
"After: b="
+ b.getName());
}
public
static
void
tripleValue(
double
x)
// doesn't work
{
x =
3
* x;
//假定一个方法,将一个参数的值 增加到三倍,但是percent的值依旧是10
System.out.println(
"End of method: x="
+ x);
}
public
static
void
tripleSalary(Employee x)
// works,对象引用作为参数,实现一个雇员的薪水提高两倍的操作,当调用harry = new Employee(。。。);tripleSalary(harry);实现改变对象参数的方法
{
x.raiseSalary(
200
);
System.out.println(
"End of method: salary="
+ x.getSalary());
}
public
static
void
swap(Employee x, Employee y)
//编写交换两个雇员对象状态的方法
{
Employee temp = x;
//swap方法的参数x和y被初始化为两个对象引用的拷贝。
x = y;
y = temp;
System.out.println(
"End of method: x="
+ x.getName());
System.out.println(
"End of method: y="
+ y.getName());
}
}
class
Employee
//simplified Employee class
{
private
String name;
private
double
salary;
public
Employee (String n,
double
s)
{
name = n;
salary = s;
}
public
String getName()
{
return
name;
}
public
double
getSalary()
{
return
salary;
}
public
void
raiseSalary(
double
byPercent)
{
double
raise = salary * byPercent /
100
;
salary += raise;
}
}
运行结果如下:
|
实验2 测试程序4(5分)
import
java.util.*;
/**
* This program demonstrates object construction.
* @version 1.02 2018-04-10
* @author Cay Horstmann
*/
public
class
ConstructorTest {
public
static
void
main(String[] args)
{
// fill the staff array with three Employee objects
Employee staff =
new
Employee[
3
];
//构建一个Employee类数组,并定义三个雇员对象
staff[
0
] =
new
Employee(
"Harry"
,
40000
);
staff[
1
] =
new
Employee(
60000
);
staff[
2
] =
new
Employee();
// print out information about all Employee objects
for
(Employee e : staff)
System.out.println(
"name="
+ e.getName() +
",
+ e.getSalary());
//调用getName方法、getId方法以及getSalary方法将每个雇员的信息打印出来
}
}
class
Employee
//在执行构造器之前,先执行赋值操作,调用方法对域进行初始化,使每个雇员有一个id域
{
private
static
int
nextId;
private
int
id;
private
String name =
""
;
// instance field initialization
private
double
salary;
// static initialization block
static
{
Employee generator =
new
Random();
// set nextId to a random number between 0 and 9999
nextId = generator.nextInt(
10000
);
}
// object initialization block
{
id = nextId;
nextId++;
}
// three overloaded constructors
public
Employee(String n,
double
s)
//通常使用单个字符命名参数
{
name = n;
salary = s;
}
public
Employee(
double
s)
{
// calls the Employee(String, double) constructor
this
(
"Employee #"
+ nextId, s);
}
// the default constructor
public
Employee()
{
// name initialized to ""--see above
// salary not explicitly set--initialized to 0
// id initialized in initialization block
}
public
String getName()
{
return
name;
}
public
double
getSalary()
{
return
salary;
}
public
int
getId()
{
return
id;
}
}
|
运行结果如下:
实验程序如下:
package com.horstmann.corejava;
// the classes in this file are part of this package 这个文件中的类就是这个包中的一部分
import java.time.*;
// import statements come after the package statement import语句位于package语句之后
/**
* @version 1.11 2015-05-08
* @author Cay Horstmann
*/
public
class
Employee
{
private
String name;
private
double
salary;
private
LocalDate hireDay;
//进行实例域定义来存放的需要操作的数据;
public
Employee(String name,
double
salary,
int
year,
int
month,
int
day)
{
this
.name = name;
this
.salary = salary;
hireDay = LocalDate.of(year, month, day);
//根据参数设置日期,参数分别为年月日;
}
//构造Employee类的对象,并声明局部变量name,salary,hireday;
public
String getName()
{
return
name;
//实例域name的访问器方法
}
public
double
getSalary()
{
return
salary;
//实例域salary的访问器方法
}
public
LocalDate getHireDay()
{
return
hireDay;
//实例域hireDay的访问器方法
}
public
void
raiseSalary(
double
byPercent)
{
double
raise = salary * byPercent / 100;
salary += raise;
//调用方法的对象salary实例域设置为新值;
}
运行结果:
4. 实验总结:(10分)
通过第四周的学习,掌握类的定义,熟悉属性、构造函数、方法的作用,掌握用类作为类型声明变量和方法返回值;理解类和对象的区别,类可以看做一个模板,我们可以根据类来创建很多的对象,而这些对象都具有我们在类中定义的方法和属性,类是抽象的,而对象是具体的。这一章主要讲解类与对象,包括面向对象程序设计的概述,使用预定义类,用户自定义类,静态域与静态方法,方法参数,对象构造等内容。Java学习已经进行到第四周,但是在代码的设计上还是没有明显的提升,在课下空余时间,我会尽力解决不会的问题,在代码的设计还是理解方面努力。通过看翁恺老师的视频讲解先把基础的内容很好的掌握。
以上是 201871010118-唐敬博《面向对象程序设计(Java)》第四周学习总结 的全部内容, 来源链接: utcz.com/z/392528.html