对象交互:一个对象当然可以由其他类的对象来组成,就像一个人体里面有心脏、肠胃一样。对象是由其他对象组成的,而类定义了这样的组合关系。
public class Display {
private int value = 0; //私有成员变量 private只能用于成员变量和成员函数前面
private int limit = 0;
public Display( int limit )
{
this.limit = limit;
}
public void increase()
{
value++;
if( value == limit )
{
value = 0;
}
}
public int getValue()
{
return value;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Display d = new Display(24);
for(;;)
{
d.increase();
System.out.println(d.getValue());
}
}
}
public class Clock {
private Display hour = new Display(24);
private Display minute = new Display(60);
public void start()
{
while( true )
{
minute.increase();
if ( minute.getValue() == 0)
{
hour.increase();
}
System.out.printf("%02d:%02d\n", hour.getValue(), minute.getValue());
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Clock clock = new Clock();
clock.start();
}
}
封装,就是把数据和对这些数据的操作放在一起,并且用这些操作把数据掩盖起来,是面向对象的基本概念之一,也是最核心的概念。
我们有一个非常直截了当的手段来保证在类的设计的时候做到封装:
-
所有的成员变量必须是private的,这样就避免别人任意使用你的内部数据;
-
所有public的函数,只是用来实现这个类的对象或类自己要提供的服务的,而不是用来直接访问数据的。除非对数据的访问就是这个类及对象的服务。简单地说,给每个成员变量提供一对用于读写的get/set函数也是不合适的设计。
对象 = 属性 + 状态
数据:属性或者状态
操作:函数
私有变量:只能在成员函数内部使用或者定义初始化的时候。私有变量在类外面不能用.运算符引用。
私有是针对类而不是对象,只有这个类内部可以访问,这个限制是对类的而不是对对象的;类内部指类的成员函数和定义初始化。
一个编译单元只有一个public类;不同类可以使用public类, 文件名必须与public类名相同,否则会报错。
package display;
public class Display {
private int value = 0;
private int limit = 0;
private static int step = 1; //在类中 private static与直接static等价
public Display( int limit )
{
this.limit = limit;
}
public void increase()
{
value++;
if( value == limit )
{
value = 0;
}
}
public int getValue()
{
return value;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Display d1 = new Display(10);
Display d2 = new Display(20);
d1.increase();
System.out.println( d1.getValue() );
System.out.println( d2.getValue() );
System.out.println( d1.step );
System.out.println( d2.step );
d1.step = 2;
System.out.println( d1.step );
System.out.println( d2.step );
step = 3;
System.out.println( d1.step );
System.out.println( d2.step );
Display.step = 4;
System.out.println( d1.step );
System.out.println( d2.step );
}
}
package clock;
import display.Display;//插入包
public class Clock {
private Display hour = new Display(24);
private Display minute = new Display(60);
public void start()
{
while( true )
{
minute.increase();
if ( minute.getValue() == 0)
{
hour.increase();
}
System.out.printf("%02d:%02d\n", hour.getValue(), minute.getValue());
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Clock clock = new Clock();
clock.start();
}
}
package包是Java的类库管理机制:当你的程序越来越大的时候,你就会需要有一个机制帮助你管理一个工程中众多的类了。包就是Java的类库管理机制,它借助文件系统的目录来管理类库,一个包就是一个目录,一个包内的所有的类必须放在一个目录下,那个目录的名字必须是包的名字。作为初学者,你可以忽略不看包,反正一切靠Eclipse。但是作为一个Java程序员,你不能不懂包。要不然,在使用别人的类库和部署你的程序的时候,会遇到不少莫名其妙的麻烦。因为,包治百病啊!
public class Display {
private int value = 0;
private int limit = 0;
private static int step = 1; //在类中 private static与直接static等价
public Display( int limit )
{
this.limit = limit;
}
public void increase()
{
value++;
if( value == limit )
{
value = 0;
}
}
public int getValue()
{
return value;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Display d1 = new Display(10);
Display d2 = new Display(20);
d1.increase();
System.out.println( d1.getValue() );
System.out.println( d2.getValue() );
System.out.println( d1.step );
System.out.println( d2.step );
d1.step = 2;
System.out.println( d1.step );
System.out.println( d2.step );
step = 3;
System.out.println( d1.step );
System.out.println( d2.step );
Display.step = 4;
System.out.println( d1.step );
System.out.println( d2.step );
}
}
类变量:private static与static等价
类函数不直接属于任何对象,在类函数中使用this会直接报错,在类函数中只能调用类变量。
1
有秒计时的数字时钟(10分)
题目内容:
这一周的编程题是需要你在课程所给的时钟程序的基础上修改而成。但是我们并不直接给你时钟程序的代码,请根据视频自己输入时钟程序的Display和Clock类的代码,然后来做这个题目。
我们需要给时钟程序加上一个表示秒的Display,然后为Clock增加以下public的成员函数:
public Clock(int hour, int minute, int second);
用hour, minute和second初始化时间。
public void tick();
“嘀嗒”一下,时间走1秒。
public String toString();
返回一个String的值,以“hh:mm:ss“的形式表示当前时间。这里每个数值都占据两位,不足两位时补0。如“00:01:22"。注意其中的冒号是西文的,不是中文的。
提示:String.format()可以用和printf一样的方式来格式化一个字符串。
另外写一个Main类,它的main函数为下面的样子,注意,必须原封不动地作为Main的main函数:
public static void main(String[] args) {
java.util.Scanner in = new java.util.Scanner(System.in);
Clock clock = new Clock(in.nextInt(), in.nextInt(), in.nextInt());
clock.tick();
System.out.println(clock);
in.close();
}
注意!在提交的时候,把Main、Clock和Display三个类的代码合并在一起,其中Main类是public的,而Clock和Display类是没有修饰符的。另外,千万注意第一行不能有package语句。
输入格式:
采用给定的main函数无需考虑输入输出。
输出格式:
采用给定的main函数无需考虑输入输出。
输入样例:
采用给定的main函数无需考虑输入输出。
输出样例:
采用给定的main函数无需考虑输入输出。
时间限制:500ms内存限制:32000kb
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
java.util.Scanner in = new java.util.Scanner(System.in);
Clock clock = new Clock(in.nextInt(), in.nextInt(), in.nextInt());
clock.tick();
System.out.println(clock);
in.close();
}
}
//单个时钟计数器
class Display
{
private int value = 0;
private int limit = 0;
//limit表示上限
public Display(int limit)
{
this.limit = limit;
}
//设置value值
public void setValue(int value)
{
this.value = value;
}
//value先是不断增加,等到达上限是value变为0
public void increase()
{
value++;
if( value == limit )
{
value = 0;
}
}
//返回value值
public int getValue()
{
return value;
}
}
//显示时分秒的时钟计数器
class Clock
{
private Display hour = new Display(24);//小时
private Display minute = new Display(60);//分钟
private Display second = new Display(60);//秒钟
//通过Display中的setValue方法来设置value1值,用hour, minute和second初始化时间。
public Clock(int hour,int minute,int second)
{
this.hour.setValue(hour);
this.minute.setValue(minute);
this.second.setValue(second);
}
// “嘀嗒”一下,时间走1秒。
public void tick()
{
second.increase();//加过之后判断是否进位
if( second.getValue() == 0 )
{
minute.increase();
if( minute.getValue() == 0 )
{
hour.increase();
}
}
}
//返回一个String的值,以“hh:mm:ss“的形式表示当前时间。这里每个数值都占据两位,不足两位时补0。如“00:01:22"。注意其中的冒号是西文的,不是中文的。
//提示:String.format()可以用和printf一样的方式来格式化一个字符串
public String toString()
{
return(String.format("%02d:%02d:%02d",hour.getValue(),minute.getValue(),second.getValue()));
}
}