(一)学习总结
1.什么是面向对象的封装性,Java中是如何实现封装性的。
封装是面向对象的第一大特性,所谓封装,就是指对外部不可见,外部只能通过对象提供的接口来访问.
封装的好处是:
1、良好的封装能够减少耦合。
2、类内部的结构可以自由修改。
3、可以对成员进行更精确的控制。
4、隐藏实现细节。
不应用封装性的类,在处理数据过程,主函数中可以随意修改值。(p.age = -20)
public class Student{
public static void main(String args[]){
Person p = new Person();
p.name="张三";
p.age=-20; //此处可以给对象p随意赋值
System.out.println("名字: "+p.name+" 年龄: "+p.age);
}
}
class Person {
String name;
int age;
}
类中属性封装之后,不可随意更改,但是可以用getset方法调用,并且年龄小于0不能成功修改
public class Student{
public static void main(String args[]){
Person p = new Person();
p.setName("张三");
p.setAge(-20); //调用set方法进行赋值
System.out.println("名字: "+p.getName()+" 年龄: "+p.getAge());
}
}
class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
//可以对对应的属性赋予操作限制,即哪些值可以对属性赋值,哪些不行,其他对外的接口必须调用这两种方法来访问属性.
public void setAge(int age) { //判断是否能够给本类属性赋值
if(age>0){
this.age = age;
}else{
this.age=0;
}
}
public int getAge() {
return age;
}
}
在开发中,类中的属性全部要封装,封装之后的属性必须通过setter和getter访问.
2.阅读下面程序,分析是否能编译通过?如果不能,说明原因。
(1)
class A{
private int secret = 5;
}
public class Test{
public static void main(String args[]){
A a = new A();
System.out.println(a.secret++);
}
}
答:很明显不能通过编译,类A中的属性sevret被封装,private声明的属性只能在本类的内部进行调用,不能在外部调用。
报错信息:The field A.secret is not visible。
(2)
public class Test{
int x = 50;
static int y = 200;
public static void method(){
System.out.println(x+y);//此处调用x出错
}
public static void main(String args[]){
Test.method();
}
}
答:不能让一个静态引用非静态字段x,static都是在类初始化的时候加载的,而非静态的变量都是在对象初始化的时候加载。
1、静态:就是在java虚拟机启动的时候,就会运行,就需要初始化到内存里的
2、非静态: 就是之后到程序运行到模块的时候,才会初始化到内存里面的。
在静态方法里面,调用了非静态的引用,程序初始化,就直接调了那些还没有初始化的非静态的引用
报错信息:Cannot make a static reference to the non-static field x
3 . 使用类的静态变量和构造方法,可以跟踪某个类创建的对象个数。声明一个图书类,数据成员为编号,书名,书价,并拥有静态数据成员册数记录图书的总数。图书编号从1000开始,每产生一个对象,则编号自动递增(利用静态变量和构造方法实现)。下面给出了测试类代码和Book类的部分代码,将代码补充完整。
class Book {
//属性封装
private int bookId;
private String bookName;
private double price;
// 声明静态变量
private static int bookNumber;
// 定义静态代码块对静态变量初始化
static {// 只执行一次
bookNumber = 1000;
}
// 构造方法
public Book() {// 空构造
}
public Book(String bookName, double price) {
this.bookName = bookName;
this.price = price;
bookId = bookNumber;
bookNumber++;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
// 定义方法求图书总册数
public static int totalBook() {
int sum = bookNumber - 1000;
return sum;
}
// 重写toString方法
public String toString() {
return "编号:" + bookId + " 名称:" + this.bookName + " 价格:" + this.price;
}
}
public class Test {
public static void main(String args[]) {
Book[] books = { new Book("c语言程序设计", 29.3), new Book("数据库原理", 30),
new Book("Java学习笔记", 68) };
System.out.println("图书总数为:" + Book.totalBook());
for (Book book : books) {
System.out.println(book.toString());
}
}
}
4.什么是单例设计模式?它具有什么特点?用单例设计模式设计一个太阳类Sun。
1.什么是单例设计模式?
单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。
特点:
A.这些类只能有一个实例;
B.这些能够自动实例化;
C.这个类对整个系统可见,即必须向整个系统提供这个实例。
一个例子:Windows 回收站。
在整个视窗系统中,回收站只能有一个实例,整个系统都使用这个惟一的实例,而且回收站自行提供自己的实例。因此,回收站是单例模式的应用。
2.如何实现单例模式
单例模式的实现通常有两种方式:“饿汉式”和“懒汉式”。
2.1 饿汉式:java实现代码如下:
Public class Singleton{
Private static final Singleton singleton = new Singleton();
Private Singleton(){
}
Public static Singleton getInstance() {
Return singleton;
}
}
小结:采用懒汉式方法实现单例模式的方法是在类的内部实例化一个静态变量singleton,这是比较好理解的,既然一个类要满足上面的A,B,C三个特点,那么很自然的能想到声明为一个类的静态变量啦。还有一点要注意的哦,那就是该类的构造方法是私有的。这样类就不提供默认的构造函数了,所以也就不可以实例化了。
2.2懒汉式:java实现代码如下:
Public class Singleton{
Private static final Singleton singleton;//未初始化
Private Singleton(){
}
Public static Singleton getInstance() {
If(singleton == null)
{
Singleton = new Singleton();
}
}
}
小结:发现这两种方式的区别了吗?懒汉式也是通过一个类的静态变量实现的。但是并没有直接初始化。而是在函数getInstance()中实例化的,也就是每次想用这个实例的时候初始化的,如果已经初始化了,那么就不用初始化了,这样也很好啊,对的,其实懒汉式是比较常用的实现方式。
class Sun{
private static Sun instance = new Sun() ;
private Sun(){ }
public static Sun getInstance(){
return instance ;
}
}
public class Test{
public static void main(String args[]){
Sun s1 = Sun.getInstance ;
Sun s2 = Sun.getInstance ;
System.out.println(s1==s2);
}
}
- 构造方法私有化(用private修饰),不能用new创建实例对象了。
- 在类内创建一个实例对象,用私有静态成员instance引用该对象。
- 定义静态方法getInstance()返回实例对象instance,可以通过类名调用方法获取类的实例对象。
class Singleton{
private Singleton(){ }
public static final Singleton instance = new Singleton() ;
}
- 构造方法私有化
- 在类内创建实例对象,用静态成员instance来引用,public允许外部访问该变量,static只能用类名访问该变量,final禁止对该变量进行修改。
5.理解Java参数传递机制,阅读下面的程序,运行结果是什么?说明理由。
public class Test {
String str = new String("你好 ");
char[] ch = { 'w','o','l','l','d' };
public static void main(String args[]) {
Test test = new Test();
test.change(test.str, test.ch);
System.out.print(test.str);
System.out.print(test.ch);
}
public void change(String str, char ch[]) {
str = "hello";
ch[0] = 'W';
}
}
运行结果:你好 Wolld
内存分析:栈内存,用来存放基本类型变量以及对象的引用变量;堆内存,用来存放new关键字创建的对象与数组;
空间图:
6.其他需要总结的内容。
-
this方法注意事项
只能在构造方法中使用this调用其他的构造方法,不能再成员方法中使用。
在构造方法中,使用this调用构造方法的语句必须放在第一行,且只能出现一次。
不能在一个类的多个构造方法中使用this互相调用,必须保留一个不用this调用其他构造方法的情况,作为出口。
(二)实验总结
实验内容:
1.按照下列要求完成类的设计
(1)设计一个日期类,用于记录年、月、日,提供对日期处理的常用方法(日期输出格式xxxx-xx-xx)。
(2)设计一个职工类,该职工类至少具有下面的属性:职工号,姓名,性别,生日,工作部门,参加工作时间,设计相应的方法。
(3)设计一个部门类,包括下列属性:部门编号,部门名称,经理,设计相应方法。
(4)设计一个测试类,采用对象数组模拟一个拥有两个部门,10个职工的单位,实现对相关信息的查询功能。
程序设计思路:把职工对象给部门类private类型的职工类数组
问题1:职工初始化问题
原因:如何对职工的出生日期工作日期初始化
解决方案:使用匿名对象new一个Date日期类
new Worker(10001, "张一 ", "男",new Date(2008,1, 1), new Date(2017, 1, 1))
好处:不在栈中引用,在堆中使用后回收。
2.设计一个计算工具类,要求:
(1)为用户提供几个常见的几何体面积和体积的算法(如球的体积和表面积,圆柱体的体积和表面积,圆锥体的体积和表面积)(可以学习使用static关键字)
(2)设计一个测试类,给出几个不同的圆柱体,圆锥体,球体的尺寸,用计算工具类分别求它们体积的累加和与表面积的累加和。
(3)设计一个测试类,随机产生球,圆柱、圆锥体的尺寸,模拟考试,要求用户回答它们的体积和面积,并判断用户的回答是否正确
程序设计思路:测试1:用数组给定尺寸,循环累加V,S。测试2:随机数选几何体,随机数选尺寸
问题1:tool类中方法返回保留两位小数
原因:double类型太长,例如3.333333333333333,用户无法猜对。
解决方案:使用String类中方法
double V = 0;
V =(4/3.0) * Pi *r*r*r; //此处求体积
String v = String.format("%.2f",V);//转化String类型,保留两位
double x = Double.parseDouble(v);//转化double
return x
3.用面向对象编程思想完成评分系统
程序设计思路:使用Comparable比较器对对象数组进行比较
public class Player implements Comparable<Player>
public int compareTo(Player o) {
if (this.endScore > o.endScore) {
return -1;
} else if (this.endScore < o.endScore) {
return 1;
}else {
return 0;
}
}
4.用面向对象编程思想编写猜拳游戏
程序设计思路:创建玩家类电脑类,在游戏类中创建电脑玩家对象进行游戏
-
使用随机种子(int)(Math.random()3+1),Math。random产生double类型随机数3是左闭右开[0-2.999999),强制转化为int型
(三)代码托管
点击此处进入码云
码云commit历史截图