第二章  Java-C++(上)


          ---
类和对象



第一节 类和对象的核心概念

1.何为java-c++?  (视频下载) (全部书籍)

很多java初学者都有c++的基础,但对java的博大精深还有所听闻,所以笔者专门分出一章叫java-c++(类和对象),c++的读者会 觉得非常轻松,大部分的知识都在c++中学过。这样会在刚接触java时, 有一种自然的亲近感。这样java初学者就可以轻松入门。


2.object和Class翻译的问题

【新手可忽略不影响继续学习】1)object直译就是"东西,物体,对象"的意思。你 觉得一个一个窗口是一个一个东西吗?照我的意思,object就应该翻译成"东西",但是好像又上不了大雅之堂,成不了书面用语,所以我当年的师长们,就 把它翻译成对象了,我怕一些小兵嘎子们还是不明白,就直截了当告诉你object就是东西,至于这三个词儿东西,物体和对象,哪个你能懂,你就用哪个!@ 马克-to-win记得师长们常说那句话,万事万物皆对象,完全可以变成,万事万物皆东西,你觉得有点道理吗?
2)class比较简单,就翻译成"类",就可以了。


3.历史上讲,对象有什么重要的? (视频下载) (全部书籍)

【新手可忽略不影响继续学习】早期的编程主要是面向过程的编程,处理的问题都相对的简单,比较过程化,换句话说,就是一步一步从开始到结束,比如第一步进入电梯,第二步关门,第三步按15层,第四步走到自家门口。。。。program有个意思是节目单,你觉得上述过程像个节目单一样吗?所以我们管它叫面向过程的program。时代在发展,我们需要编写的系统越来越复杂和庞大。过去排个序,a,b,c变量名就够了,后来出现了一大堆相关的变量,比如窗口的高和宽。这时c中出现了类似结构体Window和结构体变量win1这种东西。Window这个结构体里有高和宽,这两个属性。后来发现还是不好,需要加方法,所以就有了类和对象。@马克-to-win。


给大家补充一个结构体的例子:下面TwoNumber就是一个形式上的结构体:

class TwoNumber {
    int num1;
    int num2;
}

public class Test {
    public static void main(String[] args) {
        int a=0;
        TwoNumber A = new TwoNumber();
        a=3;
        A.num1=333;
        A.num2=333;
        System.out.println("A.num1 is "+A.num1);
       
        int b=0;
        TwoNumber B = new TwoNumber();
        b=4;
        B.num1=444;  
        B.num2=444;  
        System.out.println("B.num2 is "+B.num2);
    }
}

结果:

A.num1 is 333
B.num2 is 444

作业:
1)仿照上面的例子,用类class来做一个类似c当中的叫做Window的结构体,两个属性:width和height。之后测试。
2)仿照上面的例子,用类class来做一个类似c当中的叫做Student的结构体,两个属性:name和height。之后测试。

答案:
1)

class Window {
    int width;
    int height;
}

public class Test {
    public static void main(String[] args) {
        int a=0;
        Window baofeng = new Window();
        a=3;
        baofeng.width=333;
        baofeng.height=333;
        System.out.println("baofeng.width is "+baofeng.width);
      
        int b=0;
        Window xunlei = new Window();
        b=4;
        xunlei.width=444; 
        xunlei.height=444; 
        System.out.println("xunlei.height is "+xunlei.height);
    }
}


结果:
baofeng.width is 333
xunlei.height is 444


2)

class Student {
    String name;
    int height;
}

public class Test {
    public static void main(String[] args) {
        int a=0;
        Student first = new Student();
        a=3;
        first.name="zhangsan";
        first.height=170;
        System.out.println("first.name is "+first.name);
     
        int b=0;
        Student second = new Student();
        b=4;
        second.name="lisi";
        second.height=180;
        System.out.println("second.height is "+second.height);
    }
}

结果:
first.name is zhangsan
second.height is 180


4.object和Class配合工作原理   (视频下载) (全部书籍)

【新手可忽略不影响继续学习】 Class是"类"的意思,是抽象的,并没有具体的说是哪个东西。而object是具体的,实实在在存在的一个东西,一个物体。比如车就是一个类,而不是一个object,因为车这个概念是抽象的,并没有具体指明是哪辆车。而车牌号为京HT3113的这辆车就是一个object,因为它实实在在的存在。而另外一辆车牌号为京jw2344车是另外一个实实在在的object,这两个object属于一类叫"车"。车这一类有别于另外一类:窗体window。window是类而不是object,原因是你并没有实实在在,具体的指明,@马克-to-win是哪一个window,而我电脑上,暴风的window或迅雷的window就是两个具体的实实在在的object。

【新手可忽略不影响继续学习】 类相对于对象来讲是抽象的,但好处是可以总结提取出所有对象的共同性,比如车这类都是有四个轮子的,而window这类都有宽度,且window这类可以被关闭。这样属于window这一类的对象,比如暴风window或迅雷window都有宽度,@马克-to-win且都可以被关闭。福利来了,"关闭"这行为,所有window对象都有。具有共性的”关闭”行为如果放在类中只需放一份,而放在对象中却要放n份,我们立刻看出了类和对象协同工作的好处。好,综上所述,我们给出代码:

本章源码
class Window {
    int width;
    int height;
/*close放在类中只需放一份。省去重复工作, 每个object都可以用, 当调用baoFengObject.close();时, 以下方法被执行,其中width变量,是baoFengObject的属性,而不是xunLeiObject的属性。 */ 
    void close() {
        System.out.println("kuan" + width + "的window被关闭。");
    }
}

public class Test {
    public static void main(String[] args) {
/*Window baoFengObject = new Window();和 int a=3如出一辙, int a=3说明a是int这个类型的,而不是float
 这个类型的。Window baoFengObject = new Window(); 说明baoFengObject这个对象属于window这个类, 而不是
 车这个类的, 而且int a=3 在内存中分配了a这个空间等于3,而Window baoFengObject = new Window();时
 baoFengObject在内存 中初始化了,被分配了空间,其中width初始化成了0 @马克-to-win*/
        Window baoFengObject = new Window();
        baoFengObject.width=999;//999代表暴风
        baoFengObject.height=999;//999代表暴风
        Window xunLeiObject = new Window();
        xunLeiObject.width=111;//111代表迅雷     
        xunLeiObject.height=111;//111代表迅雷     
/*有新手怎么都不明白下面一句的意思?什么是baoFengObject.close(); ,好,在前面java一章,我们学过方法,method,子函数,这些都是一回事,close()方法,close()子函数总明白吧?这里baoFengObject.close(),说的就是调用baoFengObject的close()方法*/
        baoFengObject.close();
        xunLeiObject.close();
    }
}

结果是:
kuan999的window被关闭。
kuan111的window被关闭。


补充:c语言子函数背景知识:

public class Test {
    static void close() { //这是子函数
        System.out.println("kuan" + "的window被关闭。");
    }
    public static void main(String[] args) {
        close();//这是主函数,无输入参数,无返回值
        System.out.println("完了");
    }
}

输出结果:
kuan的window被关闭。
完了


作业:
1)做一个类名字叫Phone,有两个属性,分别叫做pinpai和jiage,再编一个方法叫print,生成一个对象叫做huawei,pinpai是字符串类型,名叫华为。jiage的类型是int,是3000。在测试类当中打印他自己的价格和品牌。再生成一个对象,叫做苹果,价格是4000元,品牌是苹果。


class Phone{
    String pinpai;
    int jiage;
   void print() {
        System.out.println(pinpai +  jiage);
    }
}

public class Test {
    public static void main(String[] args) {
        Phone huawei = new Phone();
        huawei.pinpai="华为";
        huawei.jiage=3000;
        Phone pingguo = new Phone();
        pingguo.pinpai="苹果";
        pingguo.jiage=4000;    
        huawei.print();
        pingguo.print();
    }
}

2)把过去找大数的作业改编成放在现在的类里。(专门做了一个视频一步一步的演示怎么做的。)



我们把c语言中的一个例题找大数拿来:
public class Test {
    public static void main(String[] args) {
        int a = 3;
        int b = 2;
        int k = zhaodashu(a, b);
        System.out.println(k);
    }

    static int zhaodashu(int x, int y) {
        int c = 0;
        if (x < y) {
            c = y;
        }
        if (x > y) {
            c = x;
        }
        return c;
    }
}
仿照上面的例子,做一个类MyMath,里面没有属性,但有个方法叫zhaodashu,找大数,输入参数有两个,返回值是大数。主程序测试类还是Test。

答案:

class MyMath {
    int zhaodashu(int x, int y) {
        int c = 0;
        if (x < y) {
            c = y;
        }
        if (x > y) {
            c = x;
        }
        return c;
    }
}

public class Test {
    public static void main(String[] args) {
        int a = 3;
        int b = 2;
        MyMath huawei = new MyMath();
        int k =huawei.zhaodashu(a, b);
        System.out.println(k);
    }
}


3)把上一章的9.1作业找质数,改编一下,做一个类MyMath,里面有个方法叫findPrime,找质数,输入参数有两个(上限和下限),无返回值。

5.object和Class的深入理解---属性和方法   (视频下载) (全部书籍)

抽象Abstract:【新手可忽略不影响继续学习】    (视频下载) (全部书籍)很多java 的书中都谈到了抽象abstract的概念,到底什么是抽象?马克-to-win:抽取关键相关特性(属性和方法)构成对象,用程序的方法逻辑和数据结构 属性模拟现实的世界对象。比如上节的例子,现实世界的计算机里的window很复杂,那么多像素,那么多颜色,那我们如何萃取出和我们相关的属性和方法完 成我们的客户的需求呢?这个过程就叫抽象。上例中我们只抽象出了title属性和close方法就可以满足用户需求。



【新手可忽略不影响继续学习】参见以上例子,width就是对象的属性,close就是对象的方法,简单来讲,所有对象的方法都一样,就写在类中,只写一份。对象属性的值,每个对象和每个对象都不一样。既然对于所有对象来讲,方法都一样,而只有属性不一样,能区分对象的,就只有属性了,这样来讲,观察属性,就显得尤为重要。我们可以认为,方法就是用来改变属性的。就拿上个例子来讲: @马克-to-win对于baoFengObject和xunLeiObject来讲,开始时,width属性都为0,baoFengObject.width=999;和xunLeiObject.width=111;以后,baoFengObject的width等于999, 而xunLeiObject的width等于111。

本章源码
class MyTestDate {
    int year;
    int month;

    void setDate(int y, int m) {
        year = y;
        month = m;
    }

    String toStringabc() {
        return "" + year + "/" + month ;
    }
}

public class Test {
    public static void main(String[] args) {
        /* make the coin(硬币) based on the template(模板).@马克-to-win */
        MyTestDate date = new MyTestDate();
        MyTestDate date1 = new MyTestDate();
        System.out.println("The initial date is:" + date.toStringabc());

        date.setDate(2009, 7);
        System.out.println("After setting, the date is:" + date.toStringabc());
        System.out.println("The initial date1 is:" + date1.toStringabc());
    }
}

 

result is:

The initial date is:0/0
After setting, the date is:2009/7
The initial date1 is:0/0



作业:做一个类叫两个数。类里有两个属性,x和y,类里有一个方法叫设置x,它可以设置x的大小。类里还有一个方法,是打印xy。可以把xy两个值都打印出来。提高部分:类里还有一个方法叫做增加x。这个方法可以把x和输入参数相加返回。做测试类测试。

Assignment(作业): make a class called Window which has two properties called x,y and a method called drag(dx,dy), the method of drag can change the coordination of x,y, x=x+dx; also you need to create another method called print(), which can print the current x,y coordination. In your main method, you create two objects window1,window2, then you can drag window1 or window2, then print their x,y coordination.百度翻译:做一个类叫window,他有两个属性叫x,y,1个方法,叫做拖拽drag , 方法拖拽能够改变x,y的坐标,也需要创建另外一个方法叫做print, 它能够打印当前的x,y坐标,在你的主函数当中,你创建两个对象, window1,window2,然后你能拖拽window1,window2,然后打印他们的坐标。

Assignment2(作业): make a class of SpriteHero which has two properties called x,y,experience, and a method called move(dx,dy) and hit(), print method can print out all of the properties. when hit, then experience is increased by 1. then make main to test.( initially experience value is 5. x, y is 30,30) 百度翻译:做一个类叫做精灵英雄,他有两个属性叫x,y和经验值和三个方法叫做移动,点击,打印方法,能够打印出所有的属性, 当点击的时候,经验值就被增加一, 然后做一个主函数测试,它们经验值是5。x,y是30,30。  

 

实验

本章源码
class HelloClass {
    int i;

    int getI() {
        return i;
    }

    void setI(int ii) {
        i = ii;
    }
}

public class Test {
    public static void main(String[] args) {
        HelloClass hc = new HelloClass();
        hc.setI(9);
        int ri = hc.getI();
        System.out.println(ri);
    }
}

result is: 9



第二节 类和对象的相关知识


1.构造方法(Constructor):

构造方法名字和类名是一样的。不会有返回值。当你用new关键字创建一个对象的时候,构造方法被java虚拟机调用。

1.1 用new关键字创建一个对象的时候,构造方法被java虚拟机正常调用

本章源码

package com;
class FourAng {
    double w;
    double h;


    FourAng() {
        w = 2.0;
        h = 2.0;
    }

    FourAng(double x, double y) {
        w = x;
        h = y;
    }

    double area() {
        return w*h;
    }
}

public class Test {
    public static void main(String[] args) {
        FourAng c = new FourAng();//正常调用无参构造函数。
        FourAng d = new FourAng(3, 10);//正常调用2个参数的构造函数。
        System.out.println(c.area());
        System.out.println(d.area());
    }
}

result is:
4.0
30.0


作业: a班的门关了,b班的门开了又关了。The name of method(方法) should be closeDoor(), openDoor(), the property(属性) of the class is door.


1.2 当没有任何构造函数,java编译器,会插入一个默认的构造函数   (视频下载) (全部书籍)

见下面的例子:

本章源码

class Line {
    double x = 0.02;
    double y;
}

public class Test {
    public static void main(String[] args) {
        Line c = new Line();
        System.out.println(c.x);
        System.out.println(c.y);

    }
}

结果:

0.02
0.0

编译器会把上面的代码先变成如下的形式,注意: 插入一个缺省的构造函数。里面什么也没干。


本章源码

class Circle1 {
    double x = 0.02;
    double y;
    public Circle1(){
    }

}

public class Test {
    public static void main(String[] args) {
        Circle1 c = new Circle1();
        System.out.println(c.x);
        System.out.println(c.y);

    }
}

结果:

0.02
0.0

解释一下上面的例子@马克-to-win:实验表明:最开始x=0,且y=0,后来执行构造函数之前,系统先用double x=0.02; double y=0;赋值, 之后再用构造函数的方法最后赋值。如构造函数中什么都没做就用系统开始的赋值。 

类其中的变量为final时的用法:  (视频下载) (全部书籍)

类当中final变量没有初始缺省值,必须在构造函数中赋值或直接当时赋值。否则报错。

public class Test {
    final int i;
    Test(){
        i=3;
    }
    public static void main(final String[] args) {
        Test t=new Test();
        System.out.println("i = " + t.i);
    }
}

结果:

i = 3


或者
public class Test {
    final int i=9;
    public static void main(final String[] args) {
        Test t=new Test();
        System.out.println("i = " + t.i);
    }
}
结果:
i = 9

2.重载(OverLoad):(参见第一章的7.3方法重载)

Java支持方法名重载,使得多个方法可以共享一个名字。
重载的方法参数必须有所区别,即
参数的类型不同,或
参数的顺序不同,或
参数的个数不同。( 马克-to-win: 当我试图写带着同样的输入参数,不同的返回值的两个方法时,系统直接报错。所以重载只和输入参数有关系。 when I try to write two method with same arguments ,but different return value. it directly report error. So overload only has something to do with arguments.) 


 

当一个重载的方法被调用时,Java在调用方法的参数和方法的自变量之间寻找匹配。  (视频下载) (全部书籍)
但是,这种匹配并不总是精确的。只有在找不到精确匹配时,Java的自动转换才会起作用。 (如果定义了test(int),当然先调用test(int)而不会调用test(double)。 )


本章源码

//自动类型转换 Automatic type conversions() apply to overloading.

class Overl {
    // Overload test for two integer parameters.
    void test(int a, int b) {
        System.out.println("a and b: " + a + " " + b);
    }

    // overload test for a double parameter
    void test(double a) {
        System.out.println("Inside test(double) a: " + a);
    }
}

public class Test {
    public static void main(String args[]) {
        Overl ob = new Overl();
        int i = 80;
        ob.test(i); // 没有int类型,所以调用double类型的自动转换。this will invoke test(double)
        ob.test(555.5); // 准确调用,this will invoke test(double)
        ob.test(5, 8);//准确调用
    }
}

result结果 is:


Inside test(double) a: 80.0
Inside test(double) a: 555.5
a and b: 5 8

Assignment: practice overload, make two methods,add(int a,int b), add(int a,int b,int c) 


3.一个对象可能有多个参考(One Object can have many Reference)

AClass one = new AClass();one就是这个对象的参考,有点类似指针的概念。指向生成的对象。java中不叫pointer,叫reference。为什么叫参考 呢?比如在我的书中我说,你要不懂,可以参考一下abc那本书,顺着我的指引,你就知道世界上还有abc这本书。悟出"参考"和指针之间的关系了吗?

本章源码
class PointClass {
    int length;

    void setLength(int n) {
        length = n;
    }

    int getLength() {
        return length;
    }
}

public class Test {
    public static void main(String[] args) {
        PointClass p1 = new PointClass();//p1指向生成的对象。
        PointClass p2 = p1;//p2指向p1
        PointClass p3 = new PointClass();//p3是新的
        p1.setLength(10);
        System.out.println("p1: " + p1.getLength());
        System.out.println("p2: " + p2.getLength());
        System.out.println("p3: " + p3.getLength());
    }
}





result is:

p1: 10
p2: 10
p3: 0

4.this关键字(this key word) (视频下载) (全部书籍)


继上一小节,(3.一个对象可能有多个参考)this是当中的一个参考!指向他自己。


本章源码

class MyTestDate {
    int year;
    int month;

    MyTestDate(int year, int month, int day) {
/*为了学习this的用法,本例中,我们故意用了两个相同的year,一个是全类作用范围的(整个类中都有效马克-to-win):int year; 另外一个是,只有本块儿才起作用的块作用范围的MyTestDate(int year, 这两个year不是一个year,如果把this.year = year; 变成 year = year,这两个year都成了块作用范围的那个year, 这样全类作用范围的那个year等于没赋值,还是0,输出结果就会变成0/0/0, if here you use year = year;month = month; result is 0/0/0, because this.year still is 0.local variable 's scope is less than the "this" variable's scope.
*/
        this.year = year;//this.year指前面类范围的变量 int year。
        this.month = month;
    }

    void setYear(int year) {
        this.year = year;

    }

    void setMonth(int month) {
        this.month = month;

    }


/*系统见到System.out.println,会自动调用toString,初学者没必要深究*/
    public String toString() {
        return "" + year + "/" + month ;
    }
}

public class Test {
    public static void main(String[] args) {
        MyTestDate date = new MyTestDate(2009, 7, 18);
        System.out.println(date);
        date.setYear(2009);
        date.setMonth(5);
        System.out.println(date);

        MyTestDate date1 = new MyTestDate(2009, 1, 1);
        System.out.println(date1);
        date1.setYear(2006);
        date1.setMonth(6);
        System.out.println(date1);

    }
}

result is:

2009/7
2009/5
2009/1
2006/6

 

【新手可忽略不影响继续学习】(视频下载) (全部书籍) 下面例子中setYear中的return this;返回了一个指向对象的指针,this.setMonth(8).setDay(20);是合法的,如果像原来的例子一样什么都不返回,就成了void.setMonth(8).setDay(20); 马克-to-win,系统就该报错了

class MyTestDate {
    int year;
    int month;

    MyTestDate(int year, int month, int day) {
        this.year = year;
        this.month = month;
    }

    MyTestDate setYear(int year) {
        this.year = year;
        return this;
    }

    public MyTestDate setMonth(int month) {
        this.month = month;
        return this;
    }


    public String toString() {
        return "" + year + "/" + month  ;
    }
}

public class Test {
    public static void main(String[] args) {
        MyTestDate date = new MyTestDate(2009, 7, 18);
        System.out.println(date);
        date.setYear(2009).setMonth(8);
        System.out.println(date);

        MyTestDate date1 = new MyTestDate(2009, 1, 1);
        System.out.println(date1);
        date1.setYear(2006).setMonth(6);
        System.out.println(date1);

    }
}



result is:
2009/7
2009/8
2009/1
2006/6


5.Static关键字


类变量和实例变量的区别

相对于static(静态的)或说类的, 本章开始提到的都是instance(实例的)或说对象的。 每个对象都有自己的一份儿对象域或实例域,相互之间没关系, 不共享。 我们可以从对象中访问实例变量。


类变量或说静态变量跟实例变量是不一样的,(视频下载) (全部书籍)不管创建了多少个对象,系统只为每个类变量分配一次存储空间。系统为类变量分配的内存是在执行main方法时马克-to-win, 就是在程序最最开始的时候(见下面StaticDemo的例子)。所有的对象共享了类变量。可以通过对象或者通过类本身来访问类变量。

静态方法(方法前冠以static)和实例方法(前面未冠以static)的区别  (视频下载) (全部书籍)

调用静态方法或说类方法时,可以使用类名做前缀,也可以使用某一个具体的对象名;通常使用类名。

static方法只能处理static域或静态方法。实例方法可以访问实例域, 静态域或静态方法, 记住都行。

本章源码

class StaticTest {
    static int a = 4;
    static int b = 9;
    static void call() {
        /*下一句是错误的,因为静态的不能调用实例的方法。*/
        //callins();
        System.out.println("a = " + a+"马克-to-win"+Test.c);//静态方法可以访问静态属性
    }
    void callins() {
        call();
        System.out.println("a = " + a+"实例马克-to-win"+Test.c);//静态方法可以访问静态属性
    }
}
public class Test {
    static int c = 43;
    public static void main(String args[]) {
/*刚运行到这一步时,debug观察,StaticTest.a的值就等于4,Test.c的值就等于43,
 说明系统在我们的程序一开始时,就会给所有的类变量赋值。如果是对象参考, 就是null,
 见photoshop的例子*/    
        StaticTest se =new StaticTest();
        System.out.println("开始观察StaticTest.a和Test.c");
        se.b=5;
        StaticTest.call();//静态方法用类名直接调用
        se.call();
        se.callins();
        System.out.println("b = " + StaticTest.b);//静态属性用类名直接调用
    }
}

result is:
开始观察StaticTest.a和Test.c
a = 4马克-to-win43
a = 4马克-to-win43
a = 4马克-to-win43
a = 4实例马克-to-win43
b = 5




assignment: make a method which can print "hello world!".

本章源码 

package com;
class Car{
    static int count = 0;

    Car() {
          count++;//实例方法可以访问静态变量
    }
    static int getCount(){
        return count;
    }
    int inscal()
    {
        return getCount();//实例方法可以调用静态方法。
    }
}

public class Test{
     public static void main(String[] args){
        System.out.println(Car.getCount());//it's ok
        Car c = new Car();
        System.out.println(c.getCount());//实例可以调用静态方法。马克-to-win
        System.out.println(Car.getCount());

        Car c1 = new Car();
        System.out.println(Car.getCount());
        System.out.println(c1.inscal());
}
}

 

result is:

0
1
1
2
2


 

6.Static块  (视频下载) (全部书籍)

Static块:该类的任何方法被首次触碰到时(马克-to-win: when you touch Test的main方法时),Static块被运行。可以在里面初始化你的static变量,不能访问实例变量。在所有静态变量初始化之后运行,见例子。

本章源码

class Test1{
    static {
        System.out.println("Static block Test1 initialized.");
    }
}
public class Test {
    /*下面两句话是在静态块儿之前执行,所以它的值,被静态块儿里面赋的值所覆盖掉。马克-to-win, the following two statements are before the execution of the static block.*/
    static int a = 3;
    static int b;
    int c;

    static void cal(int x) {
        System.out.println("x = " + x);
        System.out.println("a = " + a);
        System.out.println("b = " + b);
    }

    // 静态块儿Static block
    static {
        // c=9; 是错误的,will cause an error.
        System.out.println("Static block initialized.");
        a = 9;
        b = a * 4;
        System.out.println("a = " + a);
        System.out.println("b = " + b);    }

    public static void main(String args[]) {
        System.out.println("in main");
/* main and cal 都是静态块儿,所以可以这样调用,here main and cal is on the same class and same level, so can use in this way.*/
        cal(42);
        new Test1();
    }
}

结果:
Static block initialized.
a = 9
b = 36
in main
x = 42
a = 9
b = 36
Static block Test1 initialized.


Assignment: 3) bawei, static block {registration, pay tuition,} normal program is "start studying."


静态块先于构造函数执行  (视频下载) (全部书籍)

class Student {
    int age;
    String name;
    static int count;

    public Student() {
        System.out.println("in constructor");
    }
/*只执行一次。*/
    static {
        System.out.println("hello");
        count = 0;
    }
}

public class Test {
    public static void main(String[] args) {
        Student s = new Student();
        Student s1 = new Student();
    }
}

result is :

hello
in constructor
in constructor

assignment: class: School has a static member called count which records how many schools we have. count's initial value is 0, count increments in School's constructor.

assignment2: car( mercedes, BMW, static member count is increased in the constructor.)

 

assignement: 1) class Car(name,price, static TotalSum), static block initialize TotalSum=0; whenever you buy a car, constructor add money to the TotalSum. finally, print out the TotalSum.

2) make a MyMath class which has absolute and power,add(int, int), add(int, int, int)


7.对象的属性可以是另外一个对象或对象的参考 (视频下载) (全部书籍)  


通过这种方法可以迅速构建一个比较大的系统。

本章源码

class Motor {
    Light[] lights;
    Handle left, right;
    KickStart ks;
    Motor() {
        lights = new Light[2];
        lights[0] = new Light();
        lights[1] = new Light();
        left = new Handle();
        right = new Handle();
        ks=new KickStart();
    }
}

class Handle {
    Grip grip;//grip中文是把套的意思
    Handle() {
        grip = new Grip();
    }
    void turnLeft() {
        System.out.println("左转车把....");
    }
}

class Light {
    void turnon() {
        System.out.println("开灯.....");
    }
}
class KickStart {
    void kick() {
        System.out.println("踹一脚,启动.........");
    }
}
class Grip {
    void rollup() {
        System.out.println("往上转一下把套,发动.........");
    }
}

public class Test {
    public static void main(String[] args) {
        Motor myMotor = new Motor();
        System.out.println("夜间启动摩托车的步骤");
        for(int i=0;i<2;i++) myMotor.lights[i].turnon(); 
        myMotor.left.grip.rollup();
        myMotor.ks.kick();
    }
}

result is:
夜间启动摩托车的步骤
开灯.....
开灯.....
往上转一下把套,发动.........
踹一脚,启动.........

8.单态模式或单例模式(Singleton) (视频下载) (全部书籍)

单态模式有什么用呢?想一下Adobe Photoshop ,处理两张图,会启动两个photoshop吗?多耗费内存呀! ( Consider Adobe or oracle, process two images with two adobes?),所以单态模式在公司编程是非常重要的。有很多场合都要求,对象只能存在一个,多了的话就太耗费资源。(马克-to-win)

class Photoshop {
/* 通过调试发现写成 static Photoshop photoshop或static Photoshop
photoshop=null;是一样的,开始时都为null,马克-to-win,另外在调试时 可以写上观察Photoshop.photoshop的值,它是独立于任何对象之外的,从程序开始运行的main方法时, 这个值就有了, 只不过为null罢了,
*/
    static Photoshop photoshop;//这个值独立于任何对象存在,实例化任何对象之前,这个成员就有可能有值。

    static Photoshop getInstanceQixy() {
        if (photoshop == null) {
            photoshop = new Photoshop();
            System.out.println("成功创建");
        } else {
            System.out.println("已经创建了该类的实例,不能再创建!");
        }

        return photoshop;
    }

    void drawImage() {
        System.out.println("draw image using photoshop");
    }
}

public class Test {
    public static void main(String[] args) {
        Photoshop photoshopI1 = Photoshop.getInstanceQixy();
        Photoshop photoshopI2 = Photoshop.getInstanceQixy();
        System.out.println(photoshopI1 == photoshopI2);
        System.out.println(photoshopI1 == Photoshop.photoshop);                      photoshopI1.drawImage();
        Photoshop photoshopI3 = new Photoshop();
        System.out.println(photoshopI1 == photoshopI3);
    }
}

 

result is: 

成功创建
已经创建了该类的实例,不能再创建!
true
true
draw image using photoshop
false

反思一下: 如果写成:static Photoshop photoshop=new Photoshop();程序执行到main时,实例化就被执行了,而现在会在Photoshop.getInstanceQixy();时才对象实例化。执行的时机不一样。有时可能不用初始化的这么早。

class Photoshop {

    static Photoshop photoshop=new Photoshop();

    static Photoshop getInstanceQixy() {
        return photoshop;
    }

    void drawImage() {
        System.out.println("draw image using photoshop");
    }
}

public class Test {
    public static void main(String[] args) {
        Photoshop photoshopI1 = Photoshop.getInstanceQixy();
        Photoshop photoshopI2 = Photoshop.getInstanceQixy();
        System.out.println(photoshopI1 == photoshopI2);
        photoshopI1.drawImage();
        Photoshop photoshopI3 = new Photoshop();
        System.out.println(photoshopI1 == photoshopI3);
    }
}


Assignment:  make a photoshop instance using Singleton, call its method of drawImage(), additional requiredment:after the first time to activate the photoshop, from the second time on, when you activate it, it will print "you have already activate one photoshop." 



9.访问控制 (视频下载) (全部书籍)

【新手可忽略不影响继续学习】 访问控制有什么用?在软件公司里是这么用的,我们想像一种场景,在你的类中,你编了三个私有方法,马克-to-win,别人当然都用不了,但在类外,你也是用不了的,你必须,在类里再编一个公共方法,别人就能随便用了!但是如果你的公共方法调用那三个私有方法的顺序是132的话,全世界人民只能调用那个公共方法,按照132的顺序,来使用那三个私有方法,他想按照123的顺序来调用那三个私有方法,都没办法。因为这个类的发布权在你手里,全世界人民只会到你的网站去下载。如果大家有需求建议说你把顺序改成321,他们得经过你的同意,把这顺序为321的公共方法,重新加入你的类中,重新在你自己的网站打包发布,所以保护了你的知识产权马克-to-win。

 
Java的访问指示符分类 1.public(公共的,全局的) 2.private(私有的,局部的) 3.protected(受保护的) 4.默认访问级别。 

public:public成员可以被你的程序中的任何其他代码访问。 
private :private成员只能被它的类中的其他成员访问。


默认访问级别:如果不使用访问指示符,该类成员为默认访问。即在它自己的包内为public,但在它的包以外不能被存取。

封装encapsulate的概念:就是把一部分属性和方法非公有化,从而控制谁可以访问他们。 (视频下载) (全部书籍)

本章源码

class Test3 {
    int a; // default access访问
    public int b; // public access
    private int c; // private access
    // methods to access c
    void setc(int i) { // set c's value
        c = i;
    }
    int getc() { // get c's value
        return c;
    }
}

public class Test {
    public static void main(String args[]) {
        Test3 ob = new Test3();
        // These are OK,a and b may be accessed directly
        ob.a = 10;
        ob.b = 20;
        // This is not OK and will cause an error,错误
        //ob.c = 100; // Error!, 因为c是私有变量

        //你必须通过方法才能访问到c, You must access c through its methods
        ob.setc(100); // OK
        System.out.println("a,b,and c: " + ob.a + " " + ob.b + " " + ob.getc());
}
}

输出结果:
a,b,and c: 10 20 100

为了区分开public和缺省的区别,我们要引进包(package)的概念。包就像咱们磁盘上的目录一样,马克-to-win。package a;就是定义说当前的目录为a。底下编的任何的类,都会出现在当前的这个目录a里。import b;就是导入b目录当中的类资源,因为我们在运行当前目录当中的类时,需要b目录当中的类资源。导入之后,b目录当中的类随便用。(视频下载) (全部书籍)


eclipse当中如何添加包?在new class时,其中有个项, 在其中写上你的包名就可以了。注意再做底下的实验时,要分别new两个类,这样系统会产生两个文件。


package p1;
public class P1Test3 {//前面必须得加个public,否则从别的包里没法访问到这个类
    int a; // default access
    public int b; // public access
    private int c; // private access
//前面必须得加个public,否则从别的包里没法用这个方法,马克-to-win
    public void setc(int i) { // set c's value
        c = i;
    }
    public int getc() { // get c's value
        return c;
    }
}


package p2;
import p1.P1Test3;
public class Test {
    public static void main(String args[]) {
        P1Test3 ob = new P1Test3();
        // ob.a = 10;//这样写错误,这里的a必须在P1Test3类中换成public权限才可以工作, 因为是在不同的包里
        ob.b = 20;
        // ob.c = 100; // 错误Error!, c是私有的
        ob.setc(100); // OK
        System.out.println("b,and c: " + " " + ob.b + " " + ob.getc());
    }
}



输出结果:
b,and c:  20 100


assignment: a class Test has a private member called c, if you don't have a c's setter, can you modify its value except constructor?  (answer: no) How can you change the value of c?(answer: add a setter)



第三节 java的常用类


1.String  (视频下载) (全部书籍)

String类很常用,很重要。 

String不像int或float, 它是参考类型。final类型, 不能被继承,String is a Reference Type,Defined in java.lang package

常用方法:
length()
String greeting = “Hello”;
int n = greeting.length();//is 5
charAt(n)(取某个位置字符)
char first = greeting.charAt(0);
char last = greeting.charAt(4);
substring()(取子字符串)
String s = greeting.substring(0,3);//from 0 inclusive to 3 exclusive
Concatenation(链接)
String a = greeting + “ world!”+ 2009;
Equality(don’t use ==)(测试是否相等)
String s = “Hello”; s.equals(greeting);
“Hello”.equalsIgnoreCase(“hello”);(忽略大小写的测试相等)

本章源码
例子:
public class Test {
    public static void main(String args[]) {
        String letters = "abcdefghijklabcdefghijkl";
/*这里讲讲阅读源代码,control点击进入方法*/
        System.out.println("'c'在第" + letters.indexOf('c') + "个");
/* indexOf(int ch, int fromIndex) Returns the index within this string
of the first occurrence of the specified character, starting the
search at the specified index.*/
        System.out.println("'a'在第" + letters.indexOf('a', 1) + "个");
        System.out.println("'$'在第" + letters.indexOf('$') + "个");
        System.out.println("def在第" + letters.indexOf("def") + "个");
        System.out.println("'c'在第" + letters.lastIndexOf('c') + "个");
        System.out.println(letters.substring(20));// 从第20个到末尾
/*beginIndex - the beginning index, inclusive(包含). endIndex - the ending
index, exclusive(不包含).*/
        System.out.println(letters.substring(3, 6));
    }
}

result is:

'c'在第2个
'a'在第12个
'$'在第-1个
def在第3个
'c'在第14个
ijkl
def

public class Test {
    public static void main(String args[]) {
        String s, s1;
        char charArray[] = new char[8];
        s1 = new String("Hello World!");
        // s1 = "Hello World!";
        // 输出String的长度
        System.out.println(s1.length());
        s1=s1.replace("World", "mark-to-win");
        System.out.println("s1 is "+s1);
        // 使用charAt()翻转字符串
        s = "";
        for (int i = s1.length() - 1; i >= 0; i--)
            s = s + s1.charAt(i);
        System.out.println(s);

    }
}


result is:
12
s1 is Hello mark-to-win!
!niw-ot-kram olleH


String表示字符串常量:一旦创建后不会再做修改和变动的字符 串。之所以采用这种方法是因为实现固定的,不可变的字符串比实现可变的字符串更简单高效。对于那些想得到改变的字符串的情况,有一个叫做 StringBuffer的String类的友类。它的对象包含了在创建之后可被改变的字符串。String类和StringBuffer类都在 java.lang包中定义。



 

【新手可忽略不影响继续学习】(视频下载) (全部书籍)看过上面例子的童鞋一定会觉得很奇怪,s = s + s1.charAt(i); 马克-to-win, s不是老在变化吗?其实s = "";时,虚拟机会创建一个String对象,s = s + s1.charAt(i); 时,会创建一个新对象,而不是之前的s了,会导致新对象的生成,这样做次数少还没有太大的问题,如果次数多的话,很浪费空间。StringBuffer是在同一个实例上做这些事,不用生成新对象。当做的次数多的话,会节省大量空间。


java堆和栈的区别【新手可忽略不影响继续学习】 (视频下载) (全部书籍)

Java中内存分成两种:一种是栈stack,一种是堆heap。

函数中的一些基本类型的变量(int, float)和对象的引用变量(reference)都在函数的栈中,如int a = 5,有个地方先存5,之后再让a指向那个地方。w=new Window(),是w指向Window的首地址。马克-to-win,存取速度快,稍逊于寄存器, 比堆快,

函数执行完后,Java会自动释放掉为函数里变量开辟的栈内存空间,该内存空间可以立即被另作他用。

堆heap内存用来存放由new创建的对象和数组。堆内存,负责运行时(runtime, 执行生成的class文件时)数据,由JVM的自动管理。缺点是,存取速度较慢。

栈中的引用变量指向堆中的对象或数组。

栈中有共享池的概念,(视频下载) (全部书籍)比如下面例子中,sz="hello";在栈中创建一个String对象引用变量sz,然后看看栈中有没有"hello",如果没有,则将"hello"存放进栈,并令sz指向”hello”,如果已经有”hello” 则直接令sz指向“hello”。对于int, float 类型的变量也是一样的有这种共享池的概念,

对于下面程序中:ss0 = new String( "hello" );是用new()来新建对象的,(视频下载) (全部书籍)存于堆中。每调用一次就会创建一个新的对象。当然从节省空间的角度来讲,肯定不如str="hello",有童鞋一定问,那要它有什么用?当时设计编译器时,为什么要设计它?马克-to-win,那我请问你,如果在你编程序时,你还不知道字符串内容怎么办?这时就用到new String(String original),所以,什么都有什么的用处。

(注意不能看调试窗口里value id,eclipse的问题)

 
本章源码

public class Test
{
    public static void main(String args[]) {
        String str, str1, ss0, ss1, ss2, ss3, ss4;
        str = "hello";
        str1 = "hello";
        ss0 = new String("hello");
        ss1 = new String("hello");
        ss2 = new String("bye");
        ss3 = new String("chi le ma");
        ss4 = new String("chi le ma");
/* ==在测内存地址是否相同,如果相同,就证明是同一个对象。== means address space is the same.str and str1 point to the same
String constant.only one place
*/
        System.out.println(str1 == str);
        System.out.println(ss1 == ss0);
/* equals 是看内容是否相等,equals means as long as value is the same, it is the same.but == mean
memory address should be the same. */
        System.out.println(ss1.equals("hello"));
        System.out.println(str1 == "hello");
        System.out.println(ss1 == "hello");
    }
}


result is:

true
false
true
true
false

String class contains a static method, valueOf(). With it, you can create a String object from a value of any of the basic types
String pi = String.valueOf(3.14159);


String对象的运算符:“+”。用来连接两个字符串


一件需要注意的事:

你不能写如下一段程序,系统会崩溃的,马克-to-win,因为他和lang包当中的类名String冲突,所以不要用lang包当中的类名当类名。因为lang包是核心包。you can not write a program like the following, the system will collapse. because it will collide with the class with the package of java.lang, so remember that don't try to use the name of class of java.lang package. 

你可以用其他包当中的类名当类名写程序。比如io包当中File类。you can rewrite a class named File because it is java.io package. 

class String{
String(int a)
{
System.out.println("a is"+a);
}
}
public class Test {
public static void main(String[] args) {
String d=new String(8);

}
}

输出结果:

java.lang.NoSuchMethodError: main
Exception in thread "main"  



2.StringBuffer

StringBuffer:String类同等的类,它允许字符串改变(原因见上一段所说)。(视频下载) (全部书籍) Overall, this avoids creating many temporary (临时)strings, in other words, without StringBuffer, you must create many temporary strings.  StringBuffer的内部实现原理:马克-to-win,Every string buffer(缓存) has a capacity(容量). As long as the length of the character sequence contained in the string buffer does not exceed(超过) the capacity, it is not necessary to allocate(分配) a new internal buffer array. If the internal buffer overflows(满后溢出), it is automatically made larger.附带一句:从JDK5开始引入StringBuilder类,它是简易的StringBuffer,速度更快,但线程不安全

本章源码
 

public class Test {
    public static void main(String[] args) {
        StringBuffer buffer;
        buffer = new StringBuffer();
        buffer.append("1");
        System.out.println(buffer);
        buffer.append("2");
        System.out.println(buffer);
    }
}

 

result is:

1
12

assignment: make a class called MyStringBuffer(char[] buf, initial size is 5, increment is 3, test program is you repeatedly store ordinary String,(the series is "abc","def","hlj") observe the effect. 


3.Arrays:

Arrays defined in java.util package
It gives a lots of static methods to manipulate(操纵) array.

 

int[] result = new int[k];
Arrays.sort(result);

 

import java.util.Arrays;
public class Test {
    public static void main(String[] args) {
        int[] result = { 4, 5, 2, 7, 8 };
        Arrays.sort(result);//当我们用到jdk自带的sort方法时,一下就排好序了,记得第一章,我们自己排序时,有多麻烦吗?
        for (int i = 0; i < result.length; i++) {
            System.out.println("" + result[i]);
        }
    }
}

 

result is:

2
4
5
7
8




4.StringTokenizer (视频下载) (全部书籍)
StringTokenizer可以解析分隔符不是空格的情况。

例子:
import java.util.StringTokenizer;
public class Test {
    public static void main(String[] args) {
        String a = "i am an          engineer";
/*用缺省分隔符空格把a这个字符串分开来, 之后把结果放在StringTokenizer类型的st_Mark_to_win中,即使空很多个格也没问题,这为我们io那章,自己发明自己的j+语言,奠定了坚实的基础*/      
        StringTokenizer st_Mark_to_win = new StringTokenizer(a);
        //返回一共有几个字, 这里是4 个
        int count = st_Mark_to_win.countTokens();
        for (int i = 0; i < count; i++) {
            //nextToken是把下一个字取回来           
            System.out.println(st_Mark_to_win.nextToken());
        }
        System.out.println("-------------------------------");
        a = "name=lisi;age=26;title=software engineer";
/*用=或者;把a这个字符串分开来, 之后把结果放在StringTokenizer类型的st_Mark_to_win中*/
        st_Mark_to_win = new StringTokenizer(a, "=;");
        count = st_Mark_to_win.countTokens();
        for (int i = 0; i < count; i++) {
            System.out.println(st_Mark_to_win.nextToken());
        }
    }
}
结果:
i
am
an
engineer
-------------------------------
name
lisi
age
26
title
software engineer


5.日期Date相关类: 


题目1: 设置准确的时间(jdk1.1以后Date的setHours不被推荐了,所以要用Calendar设置时间(视频下载) (全部书籍)

import java.util.*;
public class Test {
    public static void main(String[] args) {
        Date date;
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.YEAR,2008);
        cal.set(Calendar.MONTH,1);
        cal.set(Calendar.DAY_OF_MONTH,23);
        cal.set(Calendar.HOUR_OF_DAY,16);//不要用Calendar.HOUR,马克-to-win,它是相对于上午和下午的
        cal.set(Calendar.MINUTE, 3);
        cal.set(Calendar.SECOND, 3);
        date=cal.getTime();
        System.out.println("date is"+date);
    }
}

结果是:
date isSat Feb 23 16:03:03 CST 2008






题目2: 按一定的格式输出时间 (视频下载) (全部书籍)

本章源码

import java.util.*;
import java.text.SimpleDateFormat;
public class Test {
    public static void main(String[] args) {
        Date date = new Date();//获取当前日期
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MMM-dd kk:mm:ss a");
        System.out.println(df.format(date));//按yyyy-MMM-dd kk:mm:ss a这个格式来格式化date
        SimpleDateFormat df1 = new SimpleDateFormat(
                "yyyyy.MMMMM.dd GGG hh:mm aaa");
        System.out.println(df1.format(date));//按yyyyy.MMMMM.dd GGG hh:mm aaa这个格式来格式化date,格式参见下表

    }
}


result is:

2014-五月-29 11:34:14 上午
02014.五月.29 公元 11:34 上午


后记:有关yyyy-MMM-dd kk:mm:ss a是什么意思,可以参考SimpleDateFormat的api文档:k: Hour in day (1-24)

Letter Date or Time Component Presentation Examples
G Era designator Text AD
y Year Year 1996; 96
M Month in year Month July; Jul; 07
w Week in year Number 27
W Week in month Number 2
D Day in year Number 189
d Day in month Number 10
F Day of week in month Number 2
E Day in week Text Tuesday; Tue
a Am/pm marker Text PM
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone RFC 822 time zone -0800

题目3.1: 把一个字符串转成日期对象 (视频下载) (全部书籍)


当我们想根据输入字符串得到一个日期对象时我们不知道,应该以什么格式写这个字符串,才能被系统正确解析,一种聪明的做法是,马克-to-win,我们先 把日期对象根据我们的格式打印出来,之后照打印出来的样子,一丝不差的写这个字符串,这个字符串必定能被系统正确解析。下面这个例子,就是先把日期对象根 据我们的格式打印出来。之后才涉及到解析。


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Test {
    public static void main(String[] args) {
        Date date;
        Calendar cal = Calendar.getInstance();
/*先把日期对象根据我们的格式打印出来 can give us some direction to parse the string to Date format.");*/
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss G W a E");
        String mDateTime=formatter.format(cal.getTime());
        System.out.println("mDateTime is"+mDateTime);
  
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss G W a E");
        Date d = null;
        try {
/*模仿之前打出来的字符串的格式,照葫芦画瓢按上面格式写下面的字符串, 之前打印出来是这样子2014-05-30 14:17:54 公元 5 下午 星期五,马克-to-win, 所以我就写成如下的样子*/         
            d = sdf.parse("2008-11-04 09:53:45 公元 2 上午 星期二");
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("mDateTime1 is"+d);

    }
}


结果是:
mDateTime is2014-05-31 15:15:30 公元 5 下午 星期六
mDateTime1 isTue Nov 04 09:53:45 CST 2008








题目3.2: 如果时间的规范是按美国,怎么处理? (视频下载) (全部书籍)

本章源码

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Test {
    public static void main(String[] args) {
        Date date;
        Calendar cal = Calendar.getInstance();
/*上面例子用的是缺省的文字: 中文,下面说明如果时间的规范是按美国,怎么处理, 比如美语下午是PM?note that if it is US, should AM or PM.*/
        SimpleDateFormat sdf = new SimpleDateFormat("M/dd/yyyy hh:mm:ss a",java.util.Locale.US);
        Date d = null;
        try {
            d = sdf.parse("05/14/2008 10:31:37 PM");
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("mDateTime2 is"+d);
    }
}
结果是:
mDateTime2 isWed May 14 22:31:37 CST 2008

题目4: 巧妙利用SimpleDateFormat根据各种信息求日期。2008-11月第6周的星期日是几号? (视频下载) (全部书籍)
本章源码

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Test {
    public static void main(String[] args) {
        SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM W E");
        java.util.Date date2 = null;
        try {
            date2 = formatter2.parse("2008-11 6 星期日");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println("mydate2 is "+ date2);
    }
}

结果是:
mydate2 is Sun Nov 30 00:00:00 CST 2008

题目5: 巧妙利用SimpleDateFormat求出: 2008-11-11是星期几?(视频下载) (全部书籍)


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Test {
    public static void main(String[] args) {
        SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");   
        Date mydate = null;
        try {
            mydate= myFormatter.parse("2008-11-11");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        SimpleDateFormat formatter4 = new SimpleDateFormat("E");
        String mydate3=formatter4.format(mydate);
        System.out.println("2008-11-11是"+ mydate3);
    }
}

结果是:
2008-11-11是星期二

题目6: 2008年2月有多少天?那年有多少天? (视频下载) (全部书籍)


import java.util.*;
public class Test {
    public static void main(String[] args) {
        Date date;
        Calendar time=Calendar.getInstance();
        // time.clear();
/*先把时间定位在2008年2月*/       
        time.set(Calendar.YEAR,2008);
        time.set(Calendar.MONTH,1);//2月对应数字1,
/* int getActualMaximum(int field) Return the maximum value that this field could have, given the
current date. 下句话是按月来讲的最大天数而不是按年来讲的最大天数,那不是29吗? */
        int day=time.getActualMaximum(Calendar.DAY_OF_MONTH);
        System.out.println("day is"+day);
/* 下句话是按年来讲的最大天数而不是按月来讲的天数,那不是366吗? */
        day=time.getActualMaximum(Calendar.DAY_OF_YEAR);
        System.out.println("day1 is"+day);
    }
}


结果是:

day is29
day1 is366




题目7: 2008年1月8日是那年中的第几星期?(视频下载) (全部书籍)

本章源码

import java.util.*;
public class Test {
    public static void main(String[] args) {
        Date date;
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.YEAR, 2008);
        cal.set(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 8);
        System.out.println("date is"+cal.getTime());
        int weekno=cal.get(Calendar.WEEK_OF_YEAR);//Calendar.WEEK_OF_YEAR是一年中第几个星期?
        System.out.println("weekno is"+weekno);
    }
}

结果是:

date isTue Jan 08 08:13:44 CST 2008
weekno is2

题目8: 2008年的第1星期星期一是几号?(视频下载) (全部书籍)
本章源码

import java.util.*;
public class Test {
    public static void main(String[] args) {
        Date date;
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.YEAR, 2008);
        cal.set(Calendar.WEEK_OF_YEAR, 1);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        System.out.println("first week Monday is "+cal.getTime());
    }
}


结果是:

first week Monday is Mon Dec 31 08:31:24 CST 2007


题目9: 2008年5月31日, 往前倒30天是哪天? (视频下载) (全部书籍)
本章源码

import java.util.*;
public class Test {
    public static void main(String[] args) {
        Date date;
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, 2008);
        cal.set(Calendar.MONTH, 4);
        cal.set(Calendar.DAY_OF_MONTH, 31);
        date = cal.getTime();
/* getTime()返回,从January 1, 1970, 00:00:00这个时候,到现在的毫秒数,
public long getTime() Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
,60l表明是长整型, 如果用60的话就是int类型,马克-to-win 会溢出的。 这样we must use 60l*60l*24l*30l*1000l, while we can not use 60*60*24*30*1000, otherwise it will overflow(溢出).
*/
        long myTime = date.getTime() - 60l * 60l * 24l * 30l * 1000l;
/* public void setTime(long time)Sets this Date object to represent a
point in time that is time milliseconds after January 1, 1970
00:00:00 GMT. */
        date.setTime(myTime);
        System.out.println("mDate is" + date);
    }
}

结果是:

mDate isThu May 01 13:06:11 CST 2008


题目10: 2008年8月27日和2008-08-24相差多少天?(视频下载) (全部书籍)

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Test {
    public static void main(String[] args) {
        Date date = null;
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
        try {
            date = myFormatter.parse("2008-08-27");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Date mydate = null;
        try {
            mydate = myFormatter.parse("2008-08-24");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        long dayl = (date.getTime() - mydate.getTime())
                / (24l * 60l * 60l * 1000l);
        System.out.println("天数是 is " + dayl);
    }
}

结果是:

天数是 is 3


Assignment:
make a class of MyArrays which implements the same function as Arrays, which also has a method called sort which is exactly the same as the current sort.

Assignment:

1) there is a Point class inside a Circle class, you can use the following code to test.

public class CircleTest{
public static void main(String[] args){
Circle c = new Circle(1,1,2.0);
System.out.println(c);
System.out.println(c.area());



c.setPoint(10,10);
System.out.println(c);
System.out.println(c.area());

c.getPoint().setX(30);
c.getPoint().setY(30);
System.out.println(c);
System.out.println(c.area());
}
}

 

hint:

public class Circle{
private Point p;
private double r;

......

 

 

public class Point{
private int x,y;

public Point(int x, int y){
this.x = x;
this.y = y;
}
.........

1.5)we have a Hero(x,y,height,width),two Monsters(x,y,height,width), when hero hit a monster, hero's hp is increased by 50,monster's hp is decreased by 40, if monster's hp is less than 0, monster die. monster will be converted to device,['1','2','3','4','5'], initially hero has 12 device slots.['0','0','0','0',.....], after hero kill a monster, the device monster is converted to will be stored into hero's some empty device slot. if monster hit the hero, hero's hp is decreased by 40. hint: when hit, we need to see whether
two objects collide or not. in main(), we set the initial positions for hero and monsters.then we ask three objects to move around.then we ask  them to hit each other, finally we print out their hp.  

2) sort a String such as "I am a teacher and work in school" according to the order of word,hint use StringTokenizer, Arrays, (see the above lecture)

3) use class to redo all of the assignments in Chapter1.