第四章:方法操作实例变量-对象的行为

该系列文章系个人读书笔记及总结性内容,任何组织和个人不得转载进行商业活动!

第四章:方法操作实例变量-对象的行为

 
状态影响行为,行为影响状态;

对象有状态和行为两种属性,对应实例变量和方法;类的每个实例可以维持自己的实例变量;
面向对象的重点之一就是 行为会依据状态来决定
    换句话说,就是方法会使用到实例变量的值;
    比如,大狗叫声的大,小狗叫声小,声音数实例变量,叫是方法;

类所描述的是对象知道什么和执行什么

    编写类时,是在描述JVM应该如何制作该类型的对象;
    任一类的每个实例都带有相同方法,但是方法可以依据实例变量的值来表现不同的行为;
    比如歌曲song是一个类,具体的音乐就是实例,播放音乐时只会播放当前名字的音乐,虽然播放方法都是相同的;
    song.play(title);

方法的参数:你可以传值给方法

    比如你可以告诉狗叫几声:dog.bark(3);
    可能会用到形参(parameter)或实参(argument)来调用传给方法的参数;

关于形式参数和实际参数,可以这样区分

    方法会运用形参,调用一方会传入实参;
    实参是传给方法的值,传入后就成了形参;
    参数跟局部(local)变量是一样的;有类型和名称,可在方法内运用;
    

如果方法需要参数,就必须传给他适当类型的值

    void bark(int numOfBarks){numOfBarks = numOfBarks - 1}
    这里调用必须传以int类型表示的值,在方法中numOfBarks可作为一般的变量使用;

你可以从方法中取返回值

    方法可以有返回值,每个方法都声明返回值类型;
    void类型,代表并没有任何返回类型;
    也可以声明一个方法,回传给调用方法指定的返回值;int giveSecret(){return 0;}
    如果你将一个方法声明有返回值,你就必须返回所声明类型的值(或声明类型兼容的值);(后续多态章节会讨论更多细节)

你可以向一个方法中传递一个以上的参数

    方法可以有多个参数,声明时以逗号分开,传入时也是;
    且方法的参数一定要以正确数量、类型和顺序来传递参数;

Java是通过值传递的,也就是说通过copy传递

    int x = 7;
    void go(int z){}
    以x为参数传入go()这个方法中,x的字节组合会被拷贝并装进z中;
    在方法中改变z的值,并不影响x的值,它只是一个copy;即方法无法改变调用方法所传入的参数;

方法只能有一个返回值,多个返回值时可以把返回类型说明为int的数组,将值装进数组中返回;如果是混合类型的多值返回,后续的ArrayList时会再讨论;

知识小问答:
如果传入的参数是对象而不是primitive主数据类型会怎样?
    在java中传递的所用东西都是值,但此值是变量所携带的值;引用对象的变量所携带的是远程控制而不是对象本身;
    若你对方法传入参数,实际上传入的是远程控制的拷贝;

一定要返回所声明的类型吗?
    可以返回会被隐含转换成声明类型的其他类型值;但若声明的类型容器小于想要返回的类型时,必须做明确转换;
    返回值也可以被忽略,Java并未要求一定要处理返回值;这代表你要的是方法的行为而不是返回值;

要点

类定义对象的所知所为;
对象所知是实例变量;
对象所为者是方法;
方法可依据实例变量来展现不同的行为;
方法可使用参数,单参或多参;
传入方法的参数必须符合声明时的数量、顺序和类型;
传入与传出方法的值类型可以隐含的方法或明确的缩小;
方法必须声明返回值;

运用参数与返回类型

Getter和Setter(正式的应该叫Accessor与Mutator):
    可以然你执行get和set;
    Getter返回实例变量的值;
    Setter取用一个参数来设定实例变量的值;

示例:
    String brand;
    String getBrand(){return brand;}
    void setBrand(String aBrand){brand = aBrand;}    
    

封装(Encapsulation)

不封装可能会很难看;
    比如通过圆点运算符来存取,就好比使用遥控器直接控制某对象的实例变量,但如果控制器落在坏人手里就糟了;
    所以我们要创建Setter方法给所有的实例变量,并寻找某种方法强制其他程序都必须通过Setter来设定变量而不是直接存取;
    这样,就可以在Setter方法中检查,确保实例变量被设定为合理的值;
    如:public void setHeight(int ht){if(ht > 0){height = ht;}}//设置身高大于0;

数据隐藏:
    从不良数据改成可以保护数据且让你还能修改数据的方式如下:
    ——使用共有与私有这两个存取修饰符(access modifier);

封装的基本原则

    将你的实例变量标记为私有的,并提供公有的getter与setter来控制存取动作;
    (当有了更多的Java设计与编写经验之后,会有许多不同做法);
        将实例变量标记为private;
        将getter与setter标记为public;

采访一个即将被封装的对象引用:
    封装会对我的实例变量加上绝对领域,因此没有人能够恶搞我的变量;(比如身高就不能是负数)
    强迫其他程序一定经过setter,如此就能检查参数并判断是否可以执行;
    setter也许可以退回不合理的值,或是抛出Exception、或者自己进行取小数点的动作;
    重点是setter中可以执行任何动作;

实例变量应该要标记为private,并通过getter与setter来存取,如此才能有机会确保实例变量值会落在合法的范围内;

示例(Code-GoodDogTestDrive.java GoodDog.java)
class GoodDogTestDrive{
    
    public static void main(String[] args){
        GoodDog one = new GoodDog();
        GoodDog two = new GoodDog();

        one.setSize(50);
        two.setSize(10);

        System.out.println(one.getSize());
        System.out.println(two.getSize());
        
        one.bark();
        two.bark();

    }
}
class GoodDog{
    
    private int size;

    public int getSize(){
        return size;
    }
    
    public void setSize(int aSize){
        size = aSize;
    }
    
    public void bark(){
        if(size > 60){
            System.out.println("big");
        }else if(size > 20){
            System.out.println("middle");
        }else{
            System.out.println("small");
        }
    }
}

log:
bogon:180131-第四章 huaqiang$ javac *.java
bogon:180131-第四章 huaqiang$ java GoodDogTestDrive
50
10
middle
small

数组中对象的行为:(已封装的对象

    数组中的对象就如同其他的对象一样,区别在于如何存取;
    pets[0].setSize(30);
    pets[0].getSize();

声明与初始化实例变量:
    变量的声明至少需要名称与类型;声明的同时也可以初始化(赋值)变量;
    但如果你没有初始实例变量时,调用getter会发生什么事?

实例变量永远都会有默认值

    integers——0
    floating points——0.0
    boolean——false
    reference——null

数字的primitive(包括char)的预设为0,boolean的预设为false,对象引用则为null;
注意null代表没有操作对象的远程控制,远程控制它是个引用而不是对象;
    

实例变量与局部变量

    实例变量是声明在类内而不是方法中;
    局部变量是声明在方法中的;
    局部变量在使用前必须初始化;(否则通不过编译)

对于方法的参数,局部变量的规则也同样适用:
    他们在方法中声明(方法的参数列表中);
    方法调用但没传参数,编译器会报错,所以方法的参数一定会被初始化,编译器会确保方法被调用时会有与声明所相符的参数;

变量的比较:(primitive主数据类型或引用)

    两个primitive主数据类型的变量比较,使用“==”;
    两个引用变量是否引用到堆上的同一对象,实用“==”;
    需要知道两个对象是否真正相等(意义上的相等),需要使用equals()方法;

这里==只用阿里比对两个变量的字节组合,实质所表示的意义则不重要;

猜你喜欢

转载自blog.csdn.net/baby_hua/article/details/79230687
今日推荐