011-static和this关键字(老杜)

目录

CodeOrder.java

InstanceCode.java

Review.java

Review02.java

StaticTest01.java

StaticTest02.java

StaticTest03.java

StaticTest04.java

StaticTest05.java

StaticTest06.java

StaticTest07.java

ThisTest01.java

ThisTest02.java

ThisTest03.java

ThisTest04.java

day14作业

Last.java

Account.java

Data.java

Man.java

WebChat.java

Woman.java

day15作业

Homework1.java

Homework2.java

Homework3.java


CodeOrder.java

//判断以下程序的执行顺序
public class CodeOrder{
    
    // 静态代码块
    static{
        System.out.println("A");
    }

    // 入口
    // A X Y C B Z
    public static void main(String[] args){
        System.out.println("Y");
        new CodeOrder();
        System.out.println("Z");
    }

    // 构造方法
    public CodeOrder(){
        System.out.println("B");
    }

    // 实例语句块
    {
        System.out.println("C");
    }

    // 静态代码块
    static {
        System.out.println("X");
    }
}

InstanceCode.java

/*
1、除了静态代码块之外,还有一种语句块叫做:实例语句块
2、实例语句在类加载时并没有执行。
3、实例语句语法?
    {
        java语句;
        java语句;
        java语句;
    }
4、实例语句块在什么时候执行?
    只要是构造方法执行,必然在构造方法执行之前,自动执行“实例语句块”中的代码。
    实际上这也是SUN公司为java程序员准备一个特殊的时机,叫做对象构建时机。
*/
public class InstanceCode{

    //入口
    public static void main(String[] args){
        System.out.println("main begin");
        new InstanceCode();
        new InstanceCode();

        new InstanceCode("abc");
        new InstanceCode("xyz");
    }


    //实例语句块
    {
        System.out.println("实例语句块执行!");    
    }

    // Constructor
    public InstanceCode(){
        System.out.println("无参数构造方法");
    }

    // Constructor
    public InstanceCode(String name){
        System.out.println("有参数的构造方法");
    }

}

/*
运行结果:
main begin
实例语句块执行!
无参数构造方法
实例语句块执行!
无参数构造方法
实例语句块执行!
有参数的构造方法
实例语句块执行!
有参数的构造方法
*/

Review.java

/*
    到目前为止一个类当中可以出现的:
        类体{
            实例变量;
            实例方法;

            静态变量;
            静态方法;

            构造方法;

            静态代码块;
            实例语句块;

            方法(){
                // 局部变量
                int i = 100;
            }
        }
*/
public class Review{ // 类
    // 类加载机制中,是这样的:在程序执行之前,凡是需要加载的类全部加载到JVM当中。
    // 先完成加载才会执行main方法。
    static{
        System.out.println("Review类加载时执行!");
    }

    // 入口
    // 静态方法
    public static void main(String[] args){
        // 局部变量
        int i = 100;

        // 完成一个对象的一连串动作。
        // 一个学生在教室先学习,学习完成之后去餐厅吃饭。
        Student s1 = new Student();

        // 先学习,所有调用学习这个实例方法。
        s1.study();

        Student s2 = new Student();
    }

}

// 学生类
class Student{

    static{
        System.out.println("Student类加载时执行!");
    }

    // 学号
    private int no; // 实例变量
    // 姓名
    private String name;

    // 学生有静态变量吗?
    // 类级别的属性
    static String job = "学习";

    {
        System.out.println("实例语句块,构造方法执行一次,这里就执行一次!");
    }

    // 构造方法
    public Student(){
        // 假设调用无参数的构造方法,默认创建的学生学号是100,名字是zhangsan
        this(100, "zhangsan"); // this() 在这里也使用了。
    }
    public Student(int no, String name){
        this.no = no; // 这里使用了this
        this.name = name;
    }

    // 封装
    // setter and getter方法
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void setNo(int no){
        this.no = no;
    }
    public int getNo(){
        return no;
    }

    // 提供两个实例方法
    public void study(){
        // 私有的是可以在本类中访问的。在其它类中必须使用set和get方法。
        //System.out.println(this.name + "正在努力的学习!");
        //System.out.println(name + "正在努力的学习!");

        // 在实例方法中调用本类其它的实例方法。
        System.out.println(this.getName() + "正在努力的学习!");
        //System.out.println(getName() + "正在努力的学习!");

        // 方法执行到此处表示学习完成了,去吃饭。
        //this.eat();        
        // this.可以省略
        // 编译器检测到eat()方法是实例方法,会自动在eat()方法前添加 this.
        eat();
    }
    
    public void eat(){ // 实例方法
        System.out.println(this.getName() + "在餐厅吃饭呢!!!");

        // 调用静态m1()方法
        // 静态方法使用“类名.”的方式访问
        // Student.m1();

        // 类名. 可以省略吗?可以。
        // java编译器会自动在m1()方法之前添加“类名.”,因为检测到m1()方法是一个静态方法。
        m1();
    }


    // 提供两个静态方法
    public static void m1(){
        System.out.println("Student's m1 method execute!");
        // 调用m2()方法
        //Student.m2();
        m2();
    }

    public static void m2(){
        System.out.println("Student's m2 method execute!");
        System.out.println("工作性质:" + job);
        // 编译器检测到job是一个静态变量,所以这里会自动在job前添加:Student.
        //System.out.println("工作性质:" + Student.job);
    }
}

/*
运行结果:
Review类加载时执行!
Student类加载时执行!
实例语句块,构造方法执行一次,这里就执行一次!
zhangsan正在努力的学习!
zhangsan在餐厅吃饭呢!!!
Student's m1 method execute!
Student's m2 method execute!
工作性质:学习
实例语句块,构造方法执行一次,这里就执行一次!
*/

Review02.java

/*
    程序再怎么变化,万变不离其宗,有一个固定的规律:
        所有的实例相关的都是先创建对象,通过“引用.”来访问。
        所有的静态相关的都是直接采用“类名.”来访问。
    
    你有发现一些问题吗?
        总有一些是需要记忆的,在这些记忆的基础之上进行分析。
    
    大结论:
        只要负责调用的方法a和被调用的方法b在同一个类当中:
            this. 可以省略
            类名. 可以省略
*/
public class Review02{

    int i = 100;

    static int j = 1000;

    public void m1(){

        // 访问其他类的静态方法
        T.t1();

        // 访问其他类的实例方法
        T t = new T();
        t.t2();
    }

    public void m2(){}

    // 实例方法
    public void x(){ // 这个方法是实例方法,执行这个方法的过程中,当前对象是存在的。
        m1();
        m2();

        m3();
        m4();

        System.out.println(i); // System.out.println(this.i);
        System.out.println(j); // System.out.println(Review02.j);
    }

    public static void m3(){}

    public static void m4(){}

    // 问?你怎么分析这个程序?
    /*
        第一步:
            main方法是静态的,JVM调用main方法的时候直接采用的是“类名.”的方式。
            所以main方法中没有this。

        第二步:
            m1() 和 m2() 方法是实例方法,按照java语法规则来说,实例方法必须先
            new对象,通过“引用.”的方式访问。
    */
    public static void main(String[] args){
        // 编译报错。
        //m1();
        //m2();

        m3(); // 编译器会自动识别m3()静态方法,结果是:Review02.m3();
        m4(); // Review02.m4();

        //System.out.println(i); // 报错
        System.out.println(j); // 1000

        // 想访问m1() m2()还有i,你在static方法中只能自己new
        Review02 r = new Review02();
        System.out.println(r.i); // 100
        r.m1();
        r.m2();

        // 局部变量,局部变量访问的时候是不需要“xxx.”的
        int k = 10000;
        System.out.println(k); // 10000
    }
}


class T{
    // 静态方法
    public static void t1(){
    
    }

    //实例方法
    public void t2(){
    
    }
}

StaticTest01.java

/*
    static:
        1、static翻译为“静态”
        2、所有static关键字修饰的都是类相关的,类级别的。
        3、所有static修饰的,都是采用“类名.”的方式访问。
        4、static修饰的变量:静态变量
        5、static修饰的方法:静态方法
    
    变量的分类:
        变量根据声明的位置进行划分:
            在方法体当中声明的变量叫做:局部变量。
            在方法体外声明的变量叫做:成员变量。
        
        成员变量又可以分为:
            实例变量
            静态变量
*/

class VarTest{

    // 以下实例的,都是对象相关的,访问时采用“引用.”的方式访问。需要先new对象。
    // 实例相关的,必须先有对象,才能访问,可能会出现空指针异常。
    // 成员变量中的实例变量
    int i;

    // 实例方法
    public void m2(){
        // 局部变量
        int x = 200;
    }


    // 以下静态的,都是类相关的,访问时采用“类名.”的方式访问。不需要new对象。
    // 不需要对象的参与即可访问。没有空指针异常的发生。
    // 成员变量中的静态变量
    static int k;

    // 静态方法
    public static void m1(){
        // 局部变量
        int m = 100;
    }
}

StaticTest02.java

/*
    什么时候变量声明为实例的,什么时候声明为静态的?
        如果这个类型的所有对象的某个属性值都是一样的,
        不建议定义为实例变量,浪费内存空间。建议定义
        为类级别特征,定义为静态变量,在方法区中只保留
        一份,节省内存开销。
    
    一个对象一份的是实例变量。
    所有对象一份的是静态变量。
*/
/*
public class StaticTest02{
    public static void main(String[] args){
        Chinese c1 = new Chinese("1231456456456456","张三","中国");
        System.out.println(c1.idCard);
        System.out.println(c1.name);
        System.out.println(c1.country);

        Chinese c2 = new Chinese("7897897896748564","李四","中国");
        System.out.println(c2.idCard);
        System.out.println(c2.name);
        System.out.println(c2.country);
    }
}

// 定义一个类:中国人
class Chinese{

    // 身份证号
    // 每一个人的身份证号不同,所以身份证号应该是实例变量,一个对象一份。
    String idCard; 

    // 姓名
    // 姓名也是一个人一个姓名,姓名也应该是实例变量。
    String name;

    // 国籍
    // 对于“中国人”这个类来说,国籍都是“中国”,不会随着对象的改变而改变。
    // 显然国籍并不是对象级别的特征。
    // 国籍属于整个类的特征。整个族的特征。
    // 假设声明为实例变量,内存图是怎样的?
    // 假设声明为静态变量,内存图又是怎样的?
    String country;

    // 无参数
    public Chinese(){
    
    }

    // 有参数
    public Chinese(String s1,String s2, String s3){
        idCard = s1;
        name = s2;
        country = s3;
    }
}
*/

public class StaticTest02{
    public static void main(String[] args){
        // 访问中国人的国籍
        // 静态变量应该使用类名.的方式访问
        System.out.println(Chinese.country); // 中国

        Chinese c1 = new Chinese("1231456456456456","张三");
        System.out.println(c1.idCard); // 1231456456456456
        System.out.println(c1.name); // 张三

        Chinese c2 = new Chinese("7897897896748564","李四");
        System.out.println(c2.idCard); // 7897897896748564
        System.out.println(c2.name); // 李四

        // idCard是实例变量,必须先new对象,通过“引用.” 访问
        // 错误: 无法从静态上下文中引用非静态 变量 idCard
        //System.out.println(Chinese.idCard);
    }
}

// 定义一个类:中国人
class Chinese{

    // 身份证号
    // 每一个人的身份证号不同,所以身份证号应该是实例变量,一个对象一份。
    String idCard; 

    // 姓名
    // 姓名也是一个人一个姓名,姓名也应该是实例变量。
    String name;

    // 国籍
    // 重点重点五颗星:加static的变量叫做静态变量
    // 静态变量在类加载时初始化,不需要new对象,静态变量的空间就开出来了。
    // 静态变量存储在方法区。
    static String country = "中国";

    // 无参数
    public Chinese(){
    
    }

    // 有参数
    public Chinese(String s1,String s2){
        idCard = s1;
        name = s2;
    }
}

StaticTest03.java

/*
    实例的:一定需要使用“引用.”来访问。

    静态的:
        建议使用“类名.”来访问,但使用“引用.”也行(不建议使用"引用.")。
        静态的如果使用“引用.”来访问会让程序员产生困惑:程序员以为是实例的呢。
    
    结论:
        空指针异常只有在什么情况下才会发生呢?
            只有在“空引用”访问“实例”相关的,都会出现空指针异常。
*/
public class StaticTest03{
    public static void main(String[] args){
        // 通过"类名."的方式访问静态变量
        System.out.println(Chinese.country); // 中国
        // 创建对象
        Chinese c1 = new Chinese("1111111", "张三");
        System.out.println(c1.idCard); // 1111111
        System.out.println(c1.name); // 张三
        System.out.println(c1.country); // 中国

        // c1是空引用
        c1 = null;
        // 分析这里会不会出现空指针异常?
        // 不会出现空指针异常。
        // 因为静态变量不需要对象的存在。
        // 实际上以下的代码在运行的时候,还是:System.out.println(Chinese.country);
        System.out.println(c1.country); // 中国

        // 这个会出现空指针异常,因为name是实例变量。
        //System.out.println(c1.name);
    }
}

class Chinese{

    // 实例变量
    String idCard;
    String name;

    // 静态变量
    static String country = "中国";

    //构造方法
    public Chinese(String x, String y){
        idCard = x;
        name = y;
    }
}

StaticTest04.java

public class StaticTest04{
    public static void main(String[] args){

        // 这是比较正规的方式,静态方法采用“类名.”
        StaticTest04.doSome(); // 静态方法doSome()执行了!

        //对象
        StaticTest04 st = new StaticTest04();
        // 用“引用.”访问
        st.doSome(); // 静态方法doSome()执行了!

        // 空引用
        st = null;
        // 不会出现空指针异常
        // 这个代码在最终执行的时候还是会转变为:StaticTest04.doSome();
        st.doSome(); // 静态方法doSome()执行了!

        // 实例方法doOther()
        // 对象级别的方法(先new对象,通过“引用.”来访问)
        //错误: 无法从静态上下文中引用非静态 方法 doOther()
        //StaticTest04.doOther();

        StaticTest04 st2 = new StaticTest04();
        st2.doOther(); // 实例方法doOther执行了!

        // 空引用
        st2 = null;
        // 空引用调用实例方法会出现什么问题?空指针异常。
        //st2.doOther();

    }

    // 静态方法(静态方法不需要new对象,直接使用“类名.”来访问)
    // 但是也可以使用“引用.”来访问,不建议用。(因为其他程序员会感到困惑。)
    public static void doSome(){
        System.out.println("静态方法doSome()执行了!");
    }

    // 实例方法(实例相关的都需要new对象,使用"引用."来访问。)
    public void doOther(){
        System.out.println("实例方法doOther执行了!");
    }
}

// 从第一天开始讲解HelloWorld到目前为止,一个类当中一共就写过这些东西。
/*
类{
    // 实例相关的都是需要new对象的,通过"引用."访问。
    实例变量;
    实例方法;

    // 静态相关的都是采用“类名.”访问。也可以使用“引用.”,只不过不建议。
    静态变量;
    静态方法;
}
*/

StaticTest05.java

/*
    对于方法来说,什么时候定义为实例方法?什么时候定义为静态方法?
        有没有参考标准。

        此方法一般都是描述了一个行为,如果说该行为必须由对象去触发。
        那么该方法定义为实例方法。

        参考标准:
            当这个方法体当中,直接访问了实例变量,这个方法一定是实例方法。

            我们以后开发中,大部分情况下,如果是工具类的话,工具类当中的方法
            一般都是静态的。(静态方法有一个优点,是不需要new对象,直接采用类名
            调用,极其方便。工具类就是为了方便,所以工具类中的方法一般都是static的。)

            什么是工具类?????
                以后讲。(工具类就是为了方便编程而开发的一些类。)
    
    类 = 属性 + 方法
        属性描述的是:状态
        方法描述的是:行为动作
    
    一个方法代表了一个动作。

    什么时候方法定义为实例方法?
        张三考试,得分90
        李四考试,得分100
        不同的对象参加考试的结果不同。
        我们可以认定“考试”这个行为是与对象相关的行为。
        建议将“考试”这个方法定义为实例方法。
*/
public class StaticTest05{
    public static void main(String[] args){
        User u = new User();
        System.out.println(u.getId()); //0

        //User.getId();

        User.printName2(); // null

        User x = new User();
        x.printName1(); // null

        // 访问T的id怎么访问
        /*
        T t = new T();
        System.out.println(t.id);
        */

        User y = new User();
        y.printName1();
    }
}

class T{
    // 实例变量
    int id;
}

// 我之前怎么说的?实例变量访问的语法机制是什么?
// 语法:引用.实例变量名
class User{

    // 实例变量,需要对象
    private int id;

    // 实例变量
    private String name; // 首先先分析的是,这个name是对象级别的,一个对象一份。

    //分析这个方法应该定义为实例方法还是静态方法呢?
    // 打印用户的名字这样的一个方法。
    public void printName1(){ 
        System.out.println(name);
    }

    public static void printName2(){
        // 输出的是一个对象的name
        //System.out.println(name);
    }

    public void setId(int i){
        id = i;
    }

    public int getId(){
        return id;
    }

    /*
    public static int getId(){
        return id;
    }
    */
}

StaticTest06.java

/*
    1、使用static关键字可以定义:静态代码块
    2、什么是静态代码块,语法是什么?
        static {
            java语句;
            java语句;
        }
    3、static静态代码块在什么时候执行呢?
        类加载时执行。并且只执行一次。
        静态代码块有这样的特征/特点。

    4、注意:静态代码块在类加载时执行,并且在main方法执行之前执行。

    5、静态代码块一般是按照自上而下的顺序执行。

    6、静态代码块有啥作用,有什么用?
        第一:静态代码块不是那么常用。(不是每一个类当中都要写的东西。)
        第二:静态代码块这种语法机制实际上是SUN公司给我们java程序员的一个特殊的时刻/时机。
        这个时机叫做:类加载时机。

    具体的业务:
        项目经理说了:大家注意了,所有我们编写的程序中,只要是类加载了,请记录一下
        类加载的日志信息(在哪年哪月哪日几时几分几秒,哪个类加载到JVM当中了)。
        思考:这些记录日志的代码写到哪里呢?
            写到静态代码块当中。
        
*/
public class StaticTest06{

    // 静态代码块(特殊的时机:类加载时机。)
    static {
        System.out.println("A");
    }

    // 一个类当中可以编写多个静态代码块
    static {
        System.out.println("B");
    }

    // 入口
    public static void main(String[] args){
        System.out.println("Hello World!");
    }

    // 编写一个静态代码块
    static{
        System.out.println("C");
    }
}

/*
A
B
C
Hello World!
*/

StaticTest07.java

/*
    栈:方法只要执行,会压栈。(局部变量)
    堆:new出来的对象都在堆中。垃圾回收器主要针对。(实例变量)
    方法区:类的信息,字节码信息,代码片段。(静态变量)

    方法的代码片段放在方法区,但是方法执行过程当中需要的内存在栈中。
*/
public class StaticTest07{
    
    // 静态变量在什么时候初始化?类加载时初始化。
    // 静态变量存储在哪里?方法区
    static int i = 100;

    // 静态代码块什么时候执行?类加载时执行。
    static {
        // 这里可以访问i吗? 可以。
        System.out.println("i = " + i); // i = 100
    }

    // 实例变量
    int k = 111; // k变量是实例变量,在构造方法执行时内存空间才会开辟。

    static {
        //k变量可以访问吗?
        // static静态代码块在类加载时执行,并且只执行一次。
        // 类加载时,k变量空间还没有开辟出来呢。
        //错误: 无法从静态上下文中引用非静态 变量 k
        //System.out.println("k = " + k);

        // 这里可以访问name吗?
        //错误: 非法前向引用
        // 静态代码块和静态变量都在类加载的时候执行,时间相同,只能靠代码的顺序来决定谁先谁后。
        //System.out.println("name = " + name);
    }

    // 静态变量在静态代码块下面。
    static String name = "zhangsan";


    //入口(main方法执行之前实际上执行了很多代码)
    public static void main(String[] args){
        System.out.println("main begin"); // main begin
        System.out.println("main over"); // main over
    }
}

/*
总结:
    到目前为止,你遇到的所有java程序,有顺序要求的是哪些?
        第一:对于一个方法来说,方法体中的代码是有顺序的,遵循自上而下的顺序执行。
        第二:静态代码块1和静态代码块2是有先后顺序的。
        第三:静态代码块和静态变量是有先后顺序的。
*/

ThisTest01.java

/*
    this:
        1、this是一个关键字,全部小写。
        2、this是什么,在内存方面是怎样的?
            一个对象一个this。
            this是一个变量,是一个引用。this保存当前对象的内存地址,指向自身。
            所以,严格意义上来说,this代表的就是“当前对象”
            this存储在堆内存当中对象的内部。

        3、this只能使用在实例方法中。谁调用这个实例方法,this就是谁。
        所以this代表的是:当前对象。

        4、“this.”大部分情况下是可以省略的。

        5、为什么this不能使用在静态方法中??????
            this代表当前对象,静态方法中不存在当前对象。
*/
public class ThisTest01{
    public static void main(String[] args){

        Customer c1 = new Customer("张三");
        c1.shopping(); // 张三正在购物!

        Customer c2 = new Customer("李四");
        c2.shopping(); // 李四正在购物!

        Customer.doSome();
    }
}

// 顾客类
class Customer{

    // 属性
    // 实例变量(必须采用“引用.”的方式访问)
    String name;   

    //构造方法
    public Customer(){
    
    }
    public Customer(String s){
        name = s;
    }

    // 顾客购物的方法
    // 实例方法
    public void shopping(){
        // 这里的this是谁?this是当前对象。
        // c1调用shopping(),this是c1
        // c2调用shopping(),this是c2
        //System.out.println(this.name + "正在购物!");

        // this. 是可以省略的。
        // this. 省略的话,还是默认访问“当前对象”的name。
        System.out.println(name + "正在购物!");
    }

    // 静态方法
    public static void doSome(){
        // this代表的是当前对象,而静态方法的调用不需要对象。矛盾了。
        // 错误: 无法从静态上下文中引用非静态 变量 this
        //System.out.println(this);
    }
}


class Student{

    // 实例变量,怎么访问?必须先new对象,通过“引用.”来访问。
    String name = "zhangsan";

    // 静态方法
    public static void m1(){
        //System.out.println(name);

        // this代表的是当前对象。
        //System.out.println(this.name);

        // 除非你这样
        Student s = new Student();
        System.out.println(s.name);

    }

    //为什么set和get方法是实例方法?
    public void setName(String s){
        name = s;
    }
    public String getName(){
        return name;
    }

    // 又回到上午的问题了?什么时候方法定义为实例方法,什么时候定义为静态方法?
    // 如果方法中直接访问了实例变量,该方法必须是实例方法。
}

ThisTest02.java

// 分析:i变量在main方法中能不能访问????

public class ThisTest02{

    // 实例变量
    int i = 100; // 这个i变量是不是必须先new对象才能访问。

    // 静态变量
    static int k = 111;

    // 静态方法
    public static void main(String[] args){
        // 错误: 无法从静态上下文中引用非静态 变量 i
        // System.out.println(i);

        // 怎么样访问i
        ThisTest02 tt = new ThisTest02();
        System.out.println(tt.i); // 100

        // 静态变量用“类名.”访问。
        System.out.println(ThisTest02.k); // 111

        // 类名. 能不能省略?
        // 可以
        System.out.println(k); // 111
    }
}

ThisTest03.java

/*
1、this可以使用在实例方法中,不能使用在静态方法中。
2、this关键字大部分情况下可以省略,什么时候不能省略呢?
    在实例方法中,或者构造方法中,为了区分局部变量和实例变量,
    这种情况下:this. 是不能省略的。
*/
public class ThisTest03{
    public static void main(String[] args){

        Student s = new Student();
        s.setNo(111);
        s.setName("张三");
        System.out.println("学号:" + s.getNo()); // 学号:111
        System.out.println("姓名:" + s.getName()); // 姓名:张三

        Student s2 = new Student(2222, "李四");
        System.out.println("学号:" + s2.getNo()); // 学号:2222
        System.out.println("姓名:" + s2.getName()); // 姓名:李四

    }
}

// 分析一下:以下代码哪里写的不好。
// 学生类
class Student{
    //学号
    private int no;

    //姓名
    private String name;

    //构造方法无参
    public Student(){
    
    }

    //构造方法有参
    /*
    public Student(int i, String s){
        no = i;
        name = s;
    }
    */

    // 上面的构造方法也增强以下可读性
    public Student(int no, String name){
        this.no = no;
        this.name = name;
    }

    // setter and getter方法
    /*
    public void setNo(int i){
        no = i;
    }
    */
    /*
    public void setNo(int no){ // 就近原则。
        no = no; //这两个no都是局部变量no,和实例变量no没关系。
    }
    */
    public void setNo(int no){ 
        //no是局部变量
        //this.no 是指的实例变量。
        this.no = no; // this. 的作用是:区分局部变量和实例变量。
    }
    public int getNo(){
        return no;
        //return this.no;
    }
    /*
    public void setName(String s){
        name = s;
    }
    */
    /*
    public void setName(String name){ // 就近原则
        name = name; //这两个name都是局部变量name,和实例变量name没关系。
    }
    */
    public void setName(String name){
        this.name = name;
    }

    /*
    public String getName(){
        return name;
    }
    */

    public String getName(){ // getName实际上获取的是“当前对象”的名字。
        //return this.name; // 严格来说,这里是有一个 this. 的。只不过这个 this. 是可以省略的。
        return name;
    }
}

ThisTest04.java

/*
    1、this除了可以使用在实例方法中,还可以用在构造方法中。
    2、新语法:通过当前的构造方法去调用另一个本类的构造方法,可以使用以下语法格式:
        this(实际参数列表);
            通过一个构造方法1去调用构造方法2,可以做到代码复用。
            但需要注意的是:“构造方法1”和“构造方法2” 都是在同一个类当中。

    3、this() 这个语法作用是什么?
        代码复用。
    
    4、死记硬背:
        对于this()的调用只能出现在构造方法的第一行。
*/
public class ThisTest04{
    public static void main(String[] args){
        // 调用无参数构造方法
        Date d1 = new Date();
        d1.detail(); // 1970年1月1日

        // 调用有参数构造方法
        Date d2 = new Date(2008, 8, 8);
        d2.detail(); // 2008年8月8日
    }
}

/*
需求:
    1、定义一个日期类,可以表示年月日信息。
    2、需求中要求:
        如果调用无参数构造方法,默认创建的日期为:1970年1月1日。
        当然,除了调用无参数构造方法之外,也可以调用有参数的构造方法来创建日期对象。
*/
class Date{ // 以后写代码都要封装,属性私有化,对外提供setter and getter
    //年
    private int year;
    //月
    private int month;
    //日
    private int day;

    // 构造方法无参
    // 调用无参数构造方法,初始化的日期是固定值。
    public Date(){
        //错误: 对this的调用必须是构造器中的第一个语句
        //System.out.println(11);
        /*
        this.year = 1970;
        this.month = 1;
        this.day = 1;
        */
        this(1970, 1, 1);
    }
    // 构造方法有参数
    public Date(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }

    // 提供一个可以打印日期的方法
    public void detail(){
        //System.out.println(year + "年" + month + "月" + day + "日");
        System.out.println(this.year + "年" + this.month + "月" + this.day + "日");
    }

    //setter and getter
    public void setYear(int year){
        // 设立关卡(有时间可以设立关卡)
        this.year = year; // 此处加this是为了区分局部变量和实例变量。
    }
    public int getYear(){
        return year;
    }
    public void setMonth(int month){
        // 设立关卡(有时间可以设立关卡)
        this.month = month;
    }
    public int getMonth(){
        return month;
    }
    public void setDay(int day){
        // 设立关卡(有时间可以设立关卡)
        this.day = day;
    }
    public int getDay(){
        return day;
    }
}

day14作业

Last.java

/*
定义丈夫类 Husband 和妻子类 Wife,
丈夫类的属性包括:身份证号,姓名,出生日期,妻子。
妻子类的属性包括:身份证号,姓名,出生日期,丈夫。
分别给这两个类提供构造方法(无参数构造方法和有参数构造方法都要提供),
编写测试程序,创建丈夫对象,然后再创建妻子对象,丈夫对象关联妻子对象,
妻子对象关联丈夫对象,要求能够输出这个“丈夫对象”的妻子的名字,
或者能够输出这个“妻子对象”的丈夫的名字。要求能够画出程序执行过程的内存图。
并且要求在程序中演示出空指针异常的效果。

别懵:
    .后面只是一个单词,没有小括号,表示访问的是属性。
    .后面有一个单词,单词后面有小括号,表示访问的是方法。

这个一定要画出内存图,很有研究价值。
*/
public class Last{
    public static void main(String[] args){
        // 创建丈夫对象(丈夫还没有妻子)
        //Husband h = new Husband("1111111", "张三", "1999-10-11", null);
        Husband h = new Husband("1111111", "张三", "1999-10-11");

        // 创建妻子对象(妻子还没有丈夫)
        //Wife w = new Wife("222222", "李四", "1989-11-10", null);
        Wife w = new Wife("222222", "李四", "1989-11-10");

        // 让他俩结婚(产生关系)
        h.wife = w;
        w.husband = h;

        // 输出丈夫对象的妻子名字
        //System.out.println(h.name + "的妻子是" + w.name); //这样写错误的。
        //当没有结婚的时候,出现:java.lang.NullPointerException
        System.out.println(h.name + "的妻子是" + h.wife.name); // 张三的妻子是李四
        System.out.println(w.name + "的丈夫是" + w.husband.name); // 李四的丈夫是张三

    }
}

// 丈夫类
class Husband{
    // 身份证号
    String idCard;
    // 姓名
    String name;
    // 生日
    String birth;
    // 妻子
    Wife wife; //实例变量

    // 无参数构造方法
    public Husband(){
    
    }

    // 有参数的构造方法
    public Husband(String s1,String s2,String s3){
        idCard = s1;
        name = s2;
        birth = s3;
    }


    // 有参数的构造方法
    public Husband(String s1,String s2,String s3, Wife w){
        idCard = s1;
        name = s2;
        birth = s3;
        wife = w;
    }

}

// 妻子类
class Wife{
    // 身份证号
    String idCard;
    // 姓名
    String name;
    // 生日
    String birth;
    // 丈夫
    Husband husband;

    // 无参数的构造方法
    public Wife(){
    
    }

    // 有参数的构造方法
    public Wife(String s1,String s2,String s3){
        idCard = s1;
        name = s2;
        birth = s3;
    }

    // 有参数构造方法
    public Wife(String s1,String s2,String s3,Husband h){
        idCard = s1;
        name = s2;
        birth = s3;
        husband = h;
    }
}

Account.java

//设计银行账户类,每个账户都有账号、密码、余额等信息。
public class Account{
    // 账号
    String actno;
    // 密码
    String password;
    // 余额
    double balance;
}

Data.java

//设计日期类,每个日期对象都可以描述年月日信息。
public class Date{
    //年
    int year;
    //月
    int month;
    //日
    int day;
}

Man.java

//设计男人类,每个男人都有身份证号、姓名、性别、女人。
public class Man{
    // 身份证号
    String idCard;
    // 姓名
    String name;
    // 性别
    static boolean sex = true;
    // 男人的女人
    // 实例变量:woman是一个引用
    Woman woman;
}

WebChat.java

//设计微信账号类,每个微信账号都有微信号、手机号、昵称等信息。
public class WebChat{
    // 账号
    String chatNo;
    // 手机号
    String mphone;
    // 昵称
    String nickname;
}

Woman.java

//设计女人类,每个女人都有身份证号、姓名、性别、男人。
public class Woman{
    // 身份证号
    String idCard;
    // 姓名
    String name;
    // 性别
    static boolean sex = false;
    // 男人
    Man man;
}

day15作业

Homework1.java

/*
请通过代码封装,实现如下需求:
    编写一个类Book,代表教材:    
    1.具有属性:名称(title)、页数(pageNum)
    2.其中页数不能少于200页,否则输出错误信息,并赋予默认值200
    3.为各属性提供赋值和取值方法
    4.具有方法:detail,用来在控制台输出每本教材的名称和页数
    5.编写测试类BookTest进行测试:为Book对象的属性赋予初始值,并调用Book对象的detail方法,看看输出是否正确
*/
public class Homework1{
    public static void main(String[] args){
        // 创建Book对象
        Book b1 = new Book("高三数学人教版", 250);
        // 调用detail方法
        b1.detail(); // 教材名称:高三数学人教版,总页数为250
        // 修改页数
        b1.setPageNum(100); // 本书页数不能少于200页,默认赋值200
        b1.detail(); // 教材名称:高三数学人教版,总页数为200

        Book b2 = new Book();
        b2.detail(); // 教材名称:未知,总页数为200
    }
}

class Book{
    // 名称
    private String title; //实例变量,引用. 的方式访问
    // 页数
    private int pageNum;

    // 构造方法,无参数
    public Book(){
        title = "未知";
        pageNum = 200;
    }

    // 有参数构造器
    public Book(String s, int i){
        title = s;
        if(i < 200){
            pageNum = 200;
            System.out.println("页数不能少于200,少于200时,页数默认为200页");
        }else{
            pageNum = i;
        }    
    }

    // setter and getter方法
    public void setTitle(String s){
        title = s;
    }
    public String getTitle(){
        return title;
    }
    public void setPageNum(int i){
        if(i < 200){
            System.out.println("本书页数不能少于200页,默认赋值200");
            // 默认赋值200
            pageNum = 200;
            return;
        }
        // 说明页数是大于等于200的。
        pageNum = i;
    }
    public int getPageNum(){
        return pageNum;
    }

    // 额外再提供一个detail方法
    public void detail(){
        //System.out.println("教材名称:" + this.title + ",总页数为" + this.pageNum);
        //this.是可以省略的
        System.out.println("教材名称:" + title + ",总页数为" + pageNum);

    }
}

Homework2.java

/*
写一个名为Account的类模拟账户。
该类的属性和方法如下所示。
该类包括的属性:账户id,余额balance,年利率annualInterestRate;
包含的方法:各属性的set和get方法。取款方法withdraw(),存款方法deposit()

写一个测试程序
(1)创建一个Customer,名字叫Jane Smith,他有一个账号为1000,余额为2000,年利率为1.23%的账户
(2)对Jane Smith操作:
存入100元,再取出960元,再取出2000。
打印Jane Smith的基本信息
信息如下显示:
成功存入:100
成功取出:960
余额不足,取钱失败
Customer [Smith,Jane] has a account :id is 1000 annualInterestRate is 1.23% balance is 1140.0
*/
public class Homework2{
    public static void main(String[] args){
        // 先创建一个账户对象
        Account a = new Account("1000", 2000, 1.23);
        // 创建客户对象
        // 传给构造方法a是什么意思?让Customer对象和Account对象产生关系。
        // 表示这个账户是Smith的。
        Customer c = new Customer("Jane Smith", a);

        /*
        对Jane Smith操作:
            存入100元,
            再取出960元,
            再取出2000。
        */
        c.getAct().deposit(100); // 成功存入:100.0
        c.getAct().withdraw(960); // 成功取出:960.0
        c.getAct().withdraw(2000); // 余额不足,取钱失败

        // 银行卡是不是应该有一个主人。
        // 此程序最难的地方是:发现对象之间的关联。不好发现。
    }
}

// 以后都是封装,所有的类都是属性私有化,对外提供setter and getter方法。
// 客户类
class Customer{
    // 客户名字
    private String name;
    // 客户手里应该有银行账户
    private Account act;

    // 构造方法
    public Customer(){
    
    }

    public Customer(String name, Account act){
        this.name = name;
        this.act = act;
    }

    // setter and getter方法
    // 为什么要写set和get,用得着吗?用不着你也得写,因为这是“封装”规定的。
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void setAct(Account act){
        this.act = act;
    }
    public Account getAct(){
        return act;
    }
}

// 账户类
class Account{
    // 账户id
    private String id;
    // 余额
    private double balance;
    // 年利率
    private double annualInterestRate;

    // 构造方法
    public Account(){
    
    }

    public Account(String id, double balance, double annualInterestRate){
        // 创建对象时需要的代码。
        this.id = id;
        this.balance = balance;
        this.annualInterestRate = annualInterestRate;
    }

    // setter and getter
    public void setId(String id){
        // 对象创建完之后,想修改id属性调用此方法。
        this.id = id;
    }
    public String getId(){
        return id;
    }
    // 实例方法(需要“引用.”来调用。)
    public void setBalance(double balance){ //修改余额的方法。
        this.balance = balance;
    }
    public double getBalance(){
        return balance;
    }
    public void setAnnualInterestRate(double annualInterestRate){
        this.annualInterestRate = annualInterestRate;
    }
    public double getAnnualInterestRate(){
        return annualInterestRate;
    }

    // 存款方法
    // 参数表示存多少钱。
    public void deposit(double money){
        // this(向this指向的对象中存款)
        //this.balance = this.balance + money;
        //this.balance += money;

        // 如果省略this.
        //balance = balance + money;
        //balance += money;

        // 调用方法来进行修改余额
        this.setBalance(this.getBalance() + money);

        // this. 可以省略。
        //setBalance(getBalance() + money);

        System.out.println("成功存入:" + money);
    }

    // 取款方法
    // 调用取钱的方法时,应该传递过来一个参数,告诉该方法要取多少钱
    public void withdraw(double money){
        // this(从this指向的对象中取款)
        if(money > this.getBalance()){
            System.out.println("余额不足,取钱失败");
            return;
        }
        // 程序能够执行到此处说明余额充足
        this.setBalance(this.getBalance() - money);
        System.out.println("成功取出:" + money);
    }
}

Homework3.java

/*
(封装)已知一个类 Student 代码如下:
class Student{
    String name;
    int age;
    String address;
    String zipCode;
    String mobile;
}
要求:
    1、把Student 的属性都作为私有,并提供get/set 方法以及适当的构造方法。
    2、为Student 类添加一个getPostAddress 方法,要求返回Student 对象的"地址"和"邮编"。
    注意:这里所说的地址是:address,不是内存地址。
*/
public class Homework3{
    public static void main(String[] args){

        Student s1 = new Student();
        System.out.println(s1.getName() + "," + s1.getPostAddress()); // null,地址:null,邮编:null

        // 赋值
        s1.setName("zhangsan");
        s1.setAge(20);
        s1.setAddress("北京朝阳区");
        s1.setZipcode("122222");
        s1.setMobile("12235224214");

        System.out.println(s1.getName() + "," + s1.getPostAddress()); // zhangsan,地址:北京朝阳区,邮编:122222

        Student s2 = new Student("李四",18,"深圳宝安区","11111","456456456456465");
        System.out.println(s2.getName() + "," + s2.getPostAddress()); // 李四,地址:深圳宝安区,邮编:11111

    }
}

class Student{
    private String name;
    private int age;
    private String address;
    private String zipcode;
    private String mobile;

    public Student(){
    
    }
    public Student(String name, int age, String address, String zipcode, String mobile){
        this.name = name;
        this.age = age;
        this.address = address;
        this.zipcode = zipcode;
        this.mobile = mobile;
    }

    // 返回地址和邮编
    public String getPostAddress(){
        return "地址:" + this.getAddress() + ",邮编:" + this.getZipcode();
        //return "地址:" + this.address + ",邮编:" + this.zipcode;
    }
    
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }

    public void setAge(int age){
        this.age = age;
    }
    public int getAge(){
        return age;
    }

    public void setAddress(String address){
        this.address = address;
    }
    public String getAddress(){
        return address;
    }

    public void setZipcode(String zipcode){
        this.zipcode = zipcode;
    }
    public String getZipcode(){
        return zipcode;
    }

    public void setMobile(String mobile){
        this.mobile = mobile;
    }
    public String getMobile(){
        return mobile;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值