该系列文章系个人读书笔记及总结性内容,任何组织和个人不得转载进行商业活动!
第二章:类与对象-拜访对象村
之前掉用过一些对象,如String;我们也可以自己设计对象类型,离开过程化的世界;
面向对象-继承(inheritance):
区分事物,实现各自的类,找出共同部分;
比如三角形(Triangle),正四边形(Square)都是shape,都可计算面积,因此提取出新的类(Shape);
将Triangle、Square以继承的关系连接到Shape这个类;
Triangle、Square 继承自Shape,计算面积方法从次级类中移开;
Shape作为父类,有两个子类;次级类会继承上级类的方法;即次级类会自动获得父类的功能;
面向对象-覆盖(override):
Triangle可以覆盖Shape的方法;Java虚拟机会知道在遇到Triangle时使用不同的计算面积方法;
覆盖的意思是由子类重新定义继承下来的方法,以改变或延伸此方法的行为;
我们已经熟悉了面向对象关键词:类、方法、属性;
类与对象:
在设计类时。需要记得对象是靠类的模型塑造出来的;
对象是已知的事物;
对象会执行的动作;
如:对象Button:已知 label、color,执行 setColor()、setLable()、dePress()、unDepress();
对象本身已知的事物被称为:实例变量(instance variable),表示状态/数据;
实例变量在每一个对象中都会有一份独立的值;
对象也可以作为实例;
对象可以执行的动作成为:方法(methods),表示行为;
对象带有读取或操作实例变量的方法很常见;
对象带有的实例变量和方法都是类设计中的一部分;
类与对象的区别:
类不是对象,却是用来创建它们的模型;
类会告诉虚拟机如何创建某种类型的对象,如使用Button类创建出不同颜色的按钮;
对象就要像通讯里中的一笔数据:
通讯录中的每张卡都有相同的空白字段(实例变量);
填入就相当于创建新的实例(对象),填好之后就是一个新的联系人;
卡片类的方法就是你要对卡片做的事,获取/修改/删除等;
所以每张卡片能够执行相同的动作,但取出的结果应该是依每张卡各自独立的;
我们创建并测试对象时可以需要两个类:
一个要被操作于对象的类;
一个用来测试该类的类;(带有main())
测试模型可以是:
编写类->编写测试用的类->在测试类中建立对象并存取对象的变量、调用方法;
这是一种过程式的测试,所有的步骤都在main()中,对于实际的面向对象程序来说,你需要用对象来与对象交互;
main()的两种用途:
测试真正的类;
启动你的Java应用程序;
真正的Java程序只会让对象与独享交互,此处说的交互是指相互调用的方法;
后续我们会看到,使用带有main()的类启动真正的Java应用程序(创建对象并让对象产生交互);
示例:(Code-GameLauncher.java)
public class GameLauncher{
public static void main(String[] args){
GuessGame game = new GuessGame();
game.startGame();
}
}
public class GuessGame{
Player p1;
Player p2;
Player p3;
public void startGame(){
p1 = new Player();
p2 = new Player();
p3 = new Player();
int guessp1 = 0;
int guessp2 = 0;
int guessp3 = 0;
boolean p1isRight = false;
boolean p2isRight = false;
boolean p3isRight = false;
int targetNumber = (int)(Math.random()*10);
System.out.println("Thinking a num between 0 and 9(Answer = " + targetNumber +")");
while(true){
p1.guess();
p2.guess();
p3.guess();
guessp1 = p1.number;
guessp2 = p2.number;
guessp3 = p3.number;
if(targetNumber == guessp1){
p1isRight = true;
}
if(targetNumber == guessp2){
p2isRight = true;
}
if(targetNumber == guessp3){
p3isRight = true;
}
if(p1isRight || p2isRight || p3isRight){
System.out.println("p1 is winner?" + p1isRight);
System.out.println("p2 is winner?" + p2isRight);
System.out.println("p3 is winner?" + p3isRight);
break;
}else{
System.out.println("Game have to try again!");
}
}
}
}
public class Player{
int number = 0;
public void guess(){
number = (int)(Math.random()*10);
System.out.println("I guess " + number);
}
}
log:
bogon:180130-第二章 huaqiang$ javac *.java
bogon:180130-第二章 huaqiang$ java GameLauncher
Thinking a num between 0 and 9(Answer = 0)
I guess 3
I guess 3
I guess 1
Game have to try again!
I guess 7
I guess 2
I guess 5
Game have to try again!
I guess 4
I guess 8
I guess 8
Game have to try again!
I guess 2
I guess 0
I guess 5
p1 is winner?false
p2 is winner?true
p3 is winner?false
Java会拾荒(垃圾回收):
创建对象时,它会被存放在称为堆的内存区域,不管对象是如何创建的都会放在此区域中;
此区域并非不同的堆;它是可以回收垃圾的堆(Garbage-Collectible Heap);
Java会根据对象的大小来分配内存空间;
Java会主动帮你管理内存;当某个对象被虚拟机察觉不再被使用,该对象就会被标记为可回收的;
如果内存开始不足,垃圾收集器就会启动来清理垃圾、回收控件,让空间能够被再次利用;
知识小问答:
若需要全局(global)变量或方法时该如何?
在Java的面向对象概念中并没有全局变量这回事;然而实际上会有需要方法或者常量(constant)可被任何程序存取;
如之前使用到的random()方法或圆周率这种常数;
后续会讨论到public和static这些让方法变成类似global的修饰符;
在任何类中的任何程序都可以存取public static的方法;
任何变量只要加上public、static和final,基本上都会变成全局变量取用的常数;
如果能做出全局的函数与数据,那又怎么算是面向对象?
Java中的事物都必须呆在类中;因此,pi常数或random()方法也必须定义在Math这个类中;
我们需要记住这个类近似全局的事物在Java中算是例外;他们是非常特殊的情况,不会有多个实例或对象;
什么是Java程序?如何进行提交?
Java程序是由一组类所组成,其中有一个类会带有启动用的main()方法;
若用户没有JVM则必须一并提交,应用程序才能运行;
若数个类如何提交?可以打包成类似单一应用程序的形式吗?
可以吧所有文件包装进依据pkzip格式来存档Java Archive-.jar文件;
在jar文件中可以引入一个简单文字格式的文字文件,被称为manifest,里面有定义出jar中的哪一个文件带有启动应用程序的main()方法;
要点小结:
面向对象设计扩展功能不需要改动已经测试好的代码;
所有Java程序都定义在类中;
类如同蓝图描述该类型的对象要如何创建;
对象自治:你无需在意他如何完成任务;
对象有已知事物,并能执行工作;
类可以继承自较为抽象的父类;
Java的程序在执行期间是一组相互交谈的对象;
class是由.java文件编译出来的;
method、instance variable呆在对象中;
object生存于堆上;
class被用来创建对象实例;