JavaSE学习总结第08天_面向对象3

时间:2023-03-09 22:06:30
JavaSE学习总结第08天_面向对象3

 

08.01 工具类中使用静态

例:

 class ArrayTool
{
//将构造方法私有,外界不能创建该类的对象
private ArrayTool(){}
//遍历数组
public static void print(int[] arr)
{
System.out.print("[");
for(int i = 0;i < arr.length;i++)
{
if(i == arr.length-1)
{
System.out.print(arr[i]+"]");
}
else
System.out.print(arr[i]+",");
}
System.out.println();
}
} class Demo
{
public static void main(String[] args)
{
int[] arr = {23,53,12,27,32,85,25};
//通过类名直接调用
ArrayTool.print(arr);
}
}

运行结果:

[23,53,12,27,32,85,25]

08.02 工具类的完善

 class ArrayTool
{
//将构造方法私有,外界不能创建该类的对象
private ArrayTool(){}
//遍历数组
public static void print(int[] arr)
{
System.out.print("[");
for(int i = 0;i < arr.length;i++)
{
if(i == arr.length-1)
{
System.out.print(arr[i]+"]");
}
else
System.out.print(arr[i]+",");
}
System.out.println();
}
//获取数组中的最大值
public static int getMax(int[] arr)
{
int max = arr[0];
for(int i = 1;i < arr.length;i++)
{
if(arr[i] > max)
max = arr[i];
}
return max;
}
//获取数组中的元素第1次出现的位置
public static int getIndex(int[] arr,int key)
{
for(int i = 0;i< arr.length;i++)
{
if(arr[i] == key)
return i;
}
return -1;
}
} class Demo
{
public static void main(String[] args)
{
int[] arr = {23,53,12,27,32,85,25};
ArrayTool.print(arr);
System.out.println("最大值是:"+ArrayTool.getMax(arr));
System.out.println("位置:"+ArrayTool.getIndex(arr,12));
}
}

运行结果:

[23,53,12,27,32,85,25]
最大值是:85
位置:2

08.03 说明书的制作过程

第1步:写一个工具类

第2步:在工具类中使用JAVA中特有的注释符/** */对代码进行注释

第3步:使用javadoc命令创建帮助文档

格式:javadoc -d 目录 -author -version ArrayTool.java

解释:

-d:输出文件的目标目录

目录:帮助文档存放的路径

-author:包含的-author信息

-version:包含的-version信息

ArrayTool.java:需要生成帮助文档的JAVA源文件

注意:类必须是公共或受保护的才可以文档化,否则,将报以下错误

JavaSE学习总结第08天_面向对象3

第4步:执行javadoc命令后会创建一个文件夹,文件夹里就是帮助文档的网页文件,点击index.html即可查看所有的注释文档

例:

 /**
* 这是对数组进行操作的工具类
* @author ZHY
* @version V1.0
*/
public class ArrayTool
{
//将构造方法私有,外界不能创建该类的对象
private ArrayTool(){}
/**
* 这是遍历数组的方法,遍历后的格式是:[元素1,元素2,元素3...]
* @param arr 需要被遍历的数组
*/
public static void print(int[] arr)
{
System.out.print("[");
for(int i = 0;i < arr.length;i++)
{
if(i == arr.length-1)
{
System.out.print(arr[i]+"]");
}
else
System.out.print(arr[i]+",");
}
System.out.println();
}
/**
* 这是获取数组中的最大值的方法
* @param arr 需要被遍历的数组
* @return 返回数组中的最大值
*/
public static int getMax(int[] arr)
{
int max = arr[0];
for(int i = 1;i < arr.length;i++)
{
if(arr[i] > max)
max = arr[i];
}
return max;
}
/**
* 这是获取数组中指定元素第1次出现的位置的方法
* @param arr 需要被查找的数组
* @param key 需要被查找的元素
* @return 返回元素第1次出现的位置,不存在则返回-1
*/
//
public static int getIndex(int[] arr,int key)
{
for(int i = 0;i< arr.length;i++)
{
if(arr[i] == key)
return i;
}
return -1;
}
}

08.04 工具类配合说明书的使用

注意:如果测试类与工具类的class文件不在同一个目录,需要设置classpath路径

08.05 如何使用JDK提供的帮助文档

1:找到文档,打开文档。

2:点击左上角的显示变成隐藏,然后点击索引

3:在输入框里面输入要找的类,然后回车。

4:看这个类的结:如果是java.lang包下的类,是可以直接使用的。否则,就需要导包才能使用。

5:看看这个类的说明以及该类的版本。

6:看这个类的结构(需不需要导包)

类的  成员变量  对应API的  字段摘要

类的  构造方法  对应API的  构造方法摘要

类的  成员方法  对应API的  方法摘要

7:看构造方法

   A:有构造方法,那么,就通过构造方法创建对象使用。

   B:没有构造方法,那么,这个类的成员一般都是静态。通过类名调用。

8:看成员方法

   左边:

      是否静态:如果静态修饰,那么可以通过类名调用。否则,就必须创建对象调用。

      是否有明确返回值:如果是void类型,就直接调用即可。否则,就可以输出或者赋值。

   右边:

      看方法名:不要写错了。

      看参数:看参数类型及个数。

08.06 通过JDK的帮助文档学习Math类的随机数功能

Math类概述:Math包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。

Math类特点:没有构造方法,因为成员都是静态的

Math类的一个方法:获取随机数

public static double random():返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。

例1:System.out.println(Math.random());

运行结果:0.7751943866930362

例2:获取1~100之间的随机数

int num = (int)(Math.random()*100)+1;

System.out.println(num);

运行结果:

86

08.07 猜数字小游戏案例

 import java.util.Scanner;
class Demo
{
public static void main(String[] args)
{
int num = (int)(Math.random()*100)+1;
//记录猜的次数
int count = 1;
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个数:");
int guess = sc.nextInt();
while(guess != num)
{
if(guess > 100 || guess < 1)
{
System.out.println("数据只能在1~100之间,请重新输入:");
guess = sc.nextInt();
}
else if(guess > num)
{
System.out.print("你猜的数"+guess+"大了,");
count++;
System.out.println("进行第"+count+"次猜数:");
guess = sc.nextInt();
}
else
{
System.out.print("你猜的数"+guess+"小了,");
count++;
System.out.println("进行第"+count+"次猜数:");
guess = sc.nextInt();
}
}
System.out.println("恭喜你,猜对了,用了"+count+"次机会");
}
}

运行结果:

JavaSE学习总结第08天_面向对象3

08.08 代码块的概述和分类

代码块:在Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程部分)。

局部代码块:在方法中出现;限定变量生命周期,及早释放,提高内存利用率

构造代码块:在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行

静态代码块:在类中方法外出现,加了static修饰在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且值执行一次。

例:

 class Code
{
static
{
int x = 10;
System.out.println("静态代码块,x="+x);
}
//构造代码块
{
int y = 10;
System.out.println("构造代码块,y="+y);
}
//构造方法
public Code()
{
System.out.println("构造方法");
}
}
class Demo
{
public static void main(String[] args)
{
new Code();
//局部代码块
{
int z = 20;
System.out.println("局部代码块,z="+z);
}
new Code();
}
}

运行结果:

静态代码块,x=10
构造代码块,y=10
构造方法
局部代码块,z=20
构造代码块,y=10
构造方法

总结:

执行顺序:静态代码块>构造代码块>构造方法

静态代码块:只执行一次

构造代码块:每次调用构造方法都执行

08.09 代码块看程序写结果

 class Student
{
static
{
System.out.println("Student 静态代码块");
} {
System.out.println("Student 构造代码块");
}
public Student()
{
System.out.println("Student 构造方法");
}
}
class Demo
{
static
{
System.out.println("Demo 静态代码块");
}
public static void main(String[] args)
{
System.out.println("main方法");
Student s1 = new Student();
Student s2 = new Student();
}
}

运行结果:

Demo 静态代码块
main方法
Student 静态代码块
Student 构造代码块
Student 构造方法
Student 构造代码块
Student 构造方法

08.10 继承的引入和概述

继承概述:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。

通过extends关键字可以实现类与类的继承:class 子类名 extends 父类名 {} 

单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类。

有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员。

08.11 继承案例和继承的好处

例:

 class Person
{
public void eat()
{
System.out.println("吃饭");
}
public void sleep()
{
System.out.println("睡觉");
}
}
//继承
class Student extends Person
{ }
//继承
class Teacher extends Person
{ }
class Demo
{
public static void main(String[] args)
{
Student s = new Student();
s.eat();
s.sleep();
Teacher t = new Teacher();
t.eat();
t.sleep();
}
}

运行结果:

吃饭
睡觉
吃饭
睡觉

继承的好处:

1.提高了代码的复用性,多个类相同的成员可以放到同一个类中

2.提高了代码的维护性,如果功能的代码需要修改,修改一处即可

3.让类与类之间产生了关系,是多态的前提。其实这也是继承的一个弊端:类的耦合性很强

08.12 继承的弊端

设计原则:低耦合高内聚

简单的理解:内聚就是自己完成某件事情的能力。耦合就是类与类之间的关系。

在设计的时候原则是:自己能完成的就不麻烦别人,这样将来别人产生了修改,就对我的影响较小。

08.13 Java中类的继承特点

1.Java只支持单继承,不支持多继承。一个类只能有一个父类,不可以有多个父类。

例:

class SubDemo extends Demo{} //正确

class SubDemo extends Demo1,Demo2...//错误

2.Java支持多层继承(继承体系)

例:

class A{}

class B extends A{}

class C extends B{}

08.14 继承的注意事项和什么时候使用继承

注意事项:

1.子类只能继承父类所有非私有的成员(成员方法和成员变量),这也体现了继承的另一个弊端:打破了封装性

2.子类不能继承父类的构造方法,但是可以通过super(后面讲解)关键字去访问父类构造方法。

3.不要为了部分功能而去继承

当继承中类与类之间体现的是:”is a”的关系就时候使用继承。例如学生是人的一种

08.15 继承中成员变量的关系

继承中成员变量的关系:

A:子类中的成员变量和父类中的成员变量名称不一样,直接调用即可。

B:子类中的成员变量和父类中的成员变量名称一样时,在子类方法中访问一个变量的查找顺序:

① 在子类方法的局部范围找,有就使用

② 在子类的成员范围找,有就使用

③ 在父类的成员范围找,有就使用

④ 如果还找不到,就报错

例:

 class Fu
{
//父类成员位置
public int num = 10;
}
class Zi extends Fu
{
//子类成员位置
public int num2 = 20;
public int num = 30;
public void show()
{
//子类方法局部位置
System.out.println(num);
System.out.println(num2);
}
}
class Demo
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
}
}

运行结果:

30
20

08.16 this和super的区别和应用

例:

 class Fu
{
public int num = 10;
}
class Zi extends Fu
{
public int num = 20;
public void show()
{
int num = 30;
//局部范围的num
System.out.println(num);
//本类成员范围的num
System.out.println(this.num);
//父类成员范围的num
System.out.println(super.num);
}
}
class Demo
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
}
}

super的用法和this很像,this代表本类对应的引用,super代表父类存储空间的标识(可以理解为父类引用)

用法:

访问成员变量: this.成员变量    super.成员变量

访问构造方法: this(...)       super(...)

访问成员方法: this.成员方法() super.成员方法()

08.17 继承中构造方法的关系

子类中所有的构造方法默认都会访问父类中空参数的构造方法

例:

 class Fu
{
Fu()
{
System.out.println("父类无参构造方法");
}
Fu(String name)
{
System.out.println("父类带参构造方法");
}
}
class Zi extends Fu
{
Zi()
{
System.out.println("子类无参构造方法");
}
Zi(String name)
{
System.out.println("子类带参构造方法");
}
}
class Demo
{
public static void main(String[] args)
{
Zi z1 = new Zi();
Zi z2 = new Zi("小明");
}
}

运行结果:

父类无参构造方法
子类无参构造方法
父类无参构造方法
子类带参构造方法

为什么子类中所有的构造方法默认都会访问父类中空参数的构造方法?

因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。

每一个构造方法的第一条语句默认都是:super()

08.18 继承中构造方法的注意事项

如何父类中没有构造方法,该怎么办呢?

如果父类没有无参的构造方法,那么子类的构造方法将报错

1.子类可以通过super去显示调用父类其他的带参的构造方法

2.子类可以通过this去调用本类的其他构造方法,本类其他构造也必须首先访问了父类构造

注意:super(...)或者this(...)必须出现在第一条语句上

08.19 继承中的面试题1

 class Fu
{
public int num = 10;
public Fu()
{
System.out.println("fu");
}
}
class Zi extends Fu
{
public int num = 20;
public Zi()
{
System.out.println("zi");
}
public void show()
{
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
class Demo
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
}
}

运行结果:

fu
zi
30
20
10

08.20 继承中的面试题2

1.静态随着类的加载而加载。

2.静态代码块>构造代码块>构造方法

3.只要有子父关系,肯定先初始化父亲的数据,然后初始化子类的数据。

 class Fu
{
static
{
System.out.println("静态代码块Fu");
} {
System.out.println("构造代码块Fu");
} public Fu()
{
System.out.println("构造方法Fu");
}
} class Zi extends Fu
{
static
{
System.out.println("静态代码块Zi");
} {
System.out.println("构造代码块Zi");
} public Zi()
{
System.out.println("构造方法Zi");
}
} class Demo
{
public static void main(String[] args)
{
Zi z = new Zi();
}
}

运行结果:

静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi

08.21 继承中的面试题3

铺垫知识:

1:成员变量有基本类型和引用类型的

2:类的初始化过程,加载class文件、堆中开辟空间、变量的默认初始化、变量的显示初始化、构造代码块初始化、构造方法初始化

3:类与类有继承关系时,先初始化父类数据,然后初始化子类数据。

 class X
{
Y b = new Y();
X()
{
System.out.print("X");
}
}
class Y
{
Y()
{
System.out.print("Y");
}
} class Demo extends X
{
Y y = new Y();
Demo()
{
     //super();super在这里仅仅表示要先初始化父类数据
System.out.print("Z");
}
public static void main(String[] args)
{
new Demo();
}
}

运行结果:

YXYZ

08.22 继承中成员方法关系

继承中成员方法的关系:

1:子类中的方法和父类中的方法声明不一样,直接调用方法即可。

2:子类中的方法和父类中的方法声明一样,通过子类对象调用方法:

① 先找子类中,看有没有这个方法,有就使用

② 再看父类中,有没有这个方法,有就使用

③ 如果没有就报错

例:

 class Fu
{
public void show()
{
System.out.println("fu show run");
}
}
class Zi extends Fu
{
public void show()
{
System.out.println("zi show run");
}
} class Demo
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
}
}

运行结果:

zi show run

08.23 方法重写的应用

方法重写概述:子类中出现了和父类中方法声明一模一样的方法,也被称为方法覆盖,方法复写。

使用特点:

如果方法名不同,就调用对应的方法

如果方法名相同,最终使用的是子类自己的

方法重写的应用:

当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。

例:

 class Phone
{
public void call(String name)
{
System.out.println("给"+name+"打电话");
}
}
class NewPhone extends Phone
{
public void call(String name)
{
//保留父类功能
super.call(name);
//定义子类特有内容
System.out.println("发图片");
}
} class Demo
{
public static void main(String[] args)
{
NewPhone np = new NewPhone();
np.call("小明");
}
}

运行结果:

给小明打电话
发图片

08.24 方法重写的注意事项

方法重写的注意事项:

1.父类中私有方法不能被重写

2.子类重写父类方法时,访问权限不能更低

3.父类静态方法,子类也必须通过静态方法进行重写

08.25 两个面试题

1.方法重写和方法重载的区别?方法重载能改变返回值类型吗?

方法重写(Override)是指在子类中出现了方法声明与父类一模一样的方法

方法重载(Overload)是指在同一个类中出现的方法名相同,参数列表不同的方法

方法重载能改变返回值类型,因为它和返回值无关

2.this关键字和super关键字分别代表什么?以及他们各自的使用场景和作用。

super的用法和this很像,this代表本类对应的引用,super代表父类存储空间的标识(可以理解为父类引用)

用法:

访问成员变量: this.成员变量    super.成员变量

访问构造方法: this(...)       super(...)

访问成员方法: this.成员方法() super.成员方法()

08.26 使用继承前的学生和老师案例

 /*
学生案例和老师案例讲解 学生:
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:getXxx()/setXxx()
老师:
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:getXxx()/setXxx()
*/
//定义学生类
class Student
{
//姓名
private String name;
//年龄
private int age; public Student()
{
} public Student(String name,int age)
{
this.name = name;
this.age = age;
} public String getName()
{
return name;
} public void setName(String name)
{
this.name = name;
} public int getAge()
{
return age;
} public void setAge(int age)
{
this.age = age;
}
} //定义老师类
class Teacher
{
//姓名
private String name;
//年龄
private int age; public Teacher()
{
} public Teacher(String name,int age)
{
this.name = name;
this.age = age;
} public String getName()
{
return name;
} public void setName(String name)
{
this.name = name;
} public int getAge()
{
return age;
} public void setAge(int age)
{
this.age = age;
}
}
class Demo
{
public static void main(String[] args)
{
//创建学生对象并测试
//方式1
Student s1 = new Student();
s1.setName("旺财");
s1.setAge(5);
System.out.println(s1.getName()+"---"+s1.getAge()); //方式2
Student s2 = new Student("旺财",5);
System.out.println(s2.getName()+"---"+s2.getAge());
}
}

08.27 使用继承后的学生和老师案例

 /*
学生案例和老师案例讲解 学生:
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:getXxx()/setXxx()
老师:
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:getXxx()/setXxx() 看上面两个类的成员,发现了很多相同的东西,所以我们就考虑抽取一个共性的类:
人:
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:getXxx()/setXxx() 学生 继承 人
老师 继承 人
*/
//定义人类
class Person
{
//姓名
private String name;
//年龄
private int age; public Person()
{
} public Person(String name,int age)
{
this.name = name;
this.age = age;
} public String getName()
{
return name;
} public void setName(String name)
{
this.name = name;
} public int getAge()
{
return age;
} public void setAge(int age)
{
this.age = age;
}
}
//定义学生类
class Student extends Person
{
Student()
{
}
Student(String name,int age)
{
super(name,age);
}
}
//定义老师类
class Teacher extends Person
{ }
class Demo
{
public static void main(String[] args)
{
//创建学生对象并测试
//方式1
Student s1 = new Student();
s1.setName("旺财");
s1.setAge(5);
System.out.println(s1.getName()+"---"+s1.getAge()); //方式2
Student s2 = new Student("旺财",5);
System.out.println(s2.getName()+"---"+s2.getAge());
}
}

08.28 猫狗案例分析

猫狗案例讲解

   先找到具体的事物,然后发现具体的事物有共性,才提取出一个父类。

   猫:

      成员变量:姓名,年龄,颜色

      构造方法:无参,带参

      成员方法:

            getXxx()/setXxx()

            eat()

            palyGame()

   狗:

      成员变量:姓名,年龄,颜色

      构造方法:无参,带参

      成员方法:

            getXxx()/setXxx()

            eat()

            lookDoor()

把共性定义到一个类中,这个类的名字叫:动物。

动物类:

      成员变量:姓名,年龄,颜色

      构造方法:无参,带参

      成员方法:

         getXxx()/setXxx()

         eat()

猫: 

   构造方法:无参,带参

   成员方法:palyGame()

狗:

   构造方法:无参,带参

   成员方法:lookDoor()

08.29 猫狗案例实现及测试

 //定义动物类
class Animal
{
//姓名
private String name;
//年龄
private int age;
//颜色
private String color; public Animal() {}
public Animal(String name,int age,String color)
{
this.name = name;
this.age = age;
this.color = color;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getColor()
{
return color;
}
public void setColor(String color)
{
this.color = color;
}
public void eat()
{
System.out.println("吃饭");
}
} //定义猫类
class Cat extends Animal
{
public Cat() {}
public Cat(String name,int age,String color)
{
super(name,age,color);
}
public void playGame()
{
System.out.println("猫玩游戏");
}
} //定义狗类
class Dog extends Animal
{
public Dog() {}
public Dog(String name,int age,String color)
{
super(name,age,color);
}
public void lookDoor()
{
System.out.println("狗看家");
}
}
class Demo
{
public static void main(String[] args)
{
//测试猫
//方式1
Cat c1 = new Cat();
c1.setName("Tom");
c1.setAge(3);
c1.setColor("黄色");
System.out.println("猫的名字是:"+c1.getName()+" 年龄是:"+c1.getAge()+" 颜色是:"+c1.getColor());
c1.eat();
c1.playGame();
System.out.println("---------------"); //方式2
Cat c2 = new Cat("旺财",5,"黑色");
System.out.println("猫的名字是:"+c2.getName()+" 年龄是:"+c2.getAge()+" 颜色是:"+c2.getColor());
c2.eat();
c2.playGame();
}
}

运行结果:

猫的名字是:Tom 年龄是:3 颜色是:黄色
吃饭
猫玩游戏
---------------
猫的名字是:旺财年龄是:5 颜色是:黑色
吃饭
猫玩游戏