深入理解面向对象(二)

1 类成员-属性

类中可以包含属性,也被称为类的成员变量,是相对于方法中的局部变量而言的。
其中属性的数据类型可以是Java的基本数据类型和引用数据类型两种。
下面的类SprinklerSystem 展示了两种数据类型的属性,分别是基本数据类型(int i,double)和引用数据类型的自定义类WaterSource。来自于Java编程思想第四版-复用类

package tony.javacore.object.composition;

import static tony.javacore.util.io.IOUtils.println;
/** * 对象的组合使用 * @author tony [email protected] * @file SprinklerSystem.java * @version 2016年2月6日下午6:26:18 * @since JDK7u80 */
public class SprinklerSystem { // 洒水车系统

    private String valve1, valve2, valve3, valve4;

    /* 实例化WaterSource对象在创建SprinklerSystem对象执行 */
    private WaterSource waterSource = new WaterSource();

    /* 基本数据类型 */
    private int i;

    private double d;

    {
        i = 87; // 代码的等价效果 private int i=47;
    }

    @Override
    public String toString() {
        return "SprinklerSystem [valve1=" + valve1 + ", valve2=" + valve2 + ", valve3=" + valve3 + ", valve4=" + valve4
                + ", waterSource=" + waterSource + ", i=" + i + ", d=" + d + "]";
    }

    public static void main(String[] args) {

        SprinklerSystem sprinklerSystem = new SprinklerSystem();

        println(sprinklerSystem); // toString方法可以让任意的对象以字符串的形式输出
    }

}

class WaterSource {

    private String s;

    WaterSource() {

        println("WaterSource()");
        s = "Constructed";

    }

    @Override
    public String toString() {
        return s;
    }
}

当一个类(SprinklerSystem )持有另一个类的引用(WaterSource waterSource)时,就使用了对象的组合。在日常开发中经常会使用这种组合的对象实现对应的功能,例如JavaEE企业级的分成开发中通常会采用分层开发的方式(MVC模式),Service层都会持有一个DAO(数据访问层)的引用用于完成数据访问的功能。

2 类成员-方法

类中可以定义若干个方法,用于完成对象或者类对应的业务逻辑。

package tony.javacore.object.method;

import static tony.javacore.util.io.IOUtils.println;

public class Storage {
    /* static修饰的变量属于类变量,不属于对象 */
    static String content = "Hello World";

    /** * 定义带返回值(int)的方法 * * @param ref * @return */
    int storage(String ref) {
        return content.length() * 2;
    }

    /** * 定义不带返回值的方法 */
    void print() {
        println("storage(storage(ref))" + storage(content));

    }

    public static void main(String[] args) {
        // 实例化对象
        Storage s = new Storage();
        // 调用对象的方法
        s.storage(content);

        s.print();
    }

}

3 方法的重载和重写

重载:同一个类中包含了两个或以上的方法名相同,方法的参数列表不同,则成为方法重载(Overload)

package tony.javacore.object.method.overload;
import static tony.javacore.util.io.IOUtils.println;
/** * 方法重载 * @author tony [email protected] * @file OverloadDog.java * @version 2016年2月6日下午6:30:08 * @since JDK7u80 */
public class OverloadDog {


    public static void main(String[] args) {

        Dog dog =new Dog();

        /*调用重载的方法*/
        dog.bark();

        dog.bark(1);

        dog.bark(1.1);
    }
}

class Dog{

    public void bark(){
        println("Dog.bark()");

    }

    public void bark(int i){
        println("Dog.bark("+i+")");
    }

    public void bark(double d){
        println("Dog.bark("+d+")");
    }

}

方法的参数顺序不同也是重载

package tony.javacore.object.method.overload;
import static tony.javacore.util.io.IOUtils.println;
/** * 重载时,方法的参数顺序不同也是重载 * @author tony [email protected] * @file OverloadingOrder.java * @version 2016年2月6日下午6:31:20 * @since JDK7u80 */
public class OverloadingOrder {

       static void showArgOrder(String str,int i){
            println("String : "+str+ " int :"+ i);
        }

        static void showArgOrder(int i,String str){
            println("int :"+ i + " String :"+str);
        }


        public static void main(String[] args) {

            showArgOrder(11, "Int First");

            showArgOrder("String First", 99);
        }

}

方法的重写:当子类继承类父类,并包含与父类同名方法的现象被称为方法重写(Override),也被称为方法覆盖。可以说子类重写了父类的方法,也可以说子类覆盖了父类的方法。
方法重写时,需要遵循方法名相同,参数列表相同,子类方法的返回类型比父类的要小,子类方法声明抛出的异常类比父类更小或者相等。

Product类分别重写了父类Product的toString()和description()方法

package tony.javacore.object.method.overload;
import static tony.javacore.util.io.IOUtils.println;

import tony.javacore.object.oop.bean.Memory;
import tony.javacore.object.oop.bean.Product;
/** * 重写父类的方法 * @author tony [email protected] * @file Computer.java * @version 2016年2月6日下午6:35:17 * @since JDK7u80 */
public class Computer extends Product {

    private Memory memory =new Memory(12);

    @Override
    public void description() {

        println("I'm a computer, memory size is "+memory.getCapacity());
    }

    @Override
    public String toString() {
        return "I'am Computer";
    }

    public static void main(String[] args) {

        Product product =new Computer();

        product.description();

        println(product);
    }
}

4 方法的参数传递机制

Java方法的参数传递机制:传递值(value),就是将实际参数的副本传入方法内,而参数本身不会受任何影响。但是引用数据类型作为参数传递时传递的是对象的地址值,在方法中修改引用地址指向的那个对象。引用地址没有改变,但是对象的内容(成员变量的值)是改变了。

package tony.javacore.object.method;
import static tony.javacore.util.io.IOUtils.println;
/** * Java方法参数传递机制 * @author tony [email protected] * @file MethodArgPassHandler.java * @version 2016年2月6日下午6:37:16 * @since JDK7u80 */
public class MethodArgPassHandler {
    public static void main(String[] args) {

        int num1 =8;
        int num2 =9;

        println("swap方法调用之前: num1 ="+num1 +" num2 ="+num2);
        PrimitveType.swap(num1,num2);
        println("swap方法调用之后:num1 ="+num1 +" num2 ="+num2);


        ReferenceType type =new ReferenceType(num1,num2);
        println("swap方法调用之前:"+type);
        ReferenceType.swap(type);
        println("swap方法调用之后:"+type);

    }
}

class PrimitveType {

    /** * 两个变量值交换 * * @param num1 * @param num2 */
    static void swap(int num1, int num2) {
        // 定义临时变量存储num1的值
        int tmp = num1;
        num1 = num2;
        num2 = tmp;

        println("swap方法中: num1 =" + num1 + " num2 =" + num2);
    }

}

class ReferenceType{



    private int num1;

    private int num2;
    public int getNum1() {
        return num1;
    }


    public void setNum1(int num1) {
        this.num1 = num1;
    }


    public int getNum2() {
        return num2;
    }


    public void setNum2(int num2) {
        this.num2 = num2;
    }


     public ReferenceType(int num1,int num2) {
         this.num1=num1;
         this.num2=num2;
    }


    @Override
    public String toString() {
        return "ReferenceType [num1=" + num1 + ", num2=" + num2 + "]";
    }


    /** * 交换引用类型成员变量的值 * @param type */
    public static void swap(ReferenceType type){
        int tmp =type.getNum1();
        type.setNum1(type.getNum2());
        type.setNum2(tmp);

        println("swap方法中:"+type);
    }
}

5 JDK5.0新特性之可变参数列表

可变参数列表是JDK5.0提供的新特性,如果在某一个类型后跟省略号,则可以表示该参数可以是任意个数的同类型变量(0-n之间)。此时与Object[]数组不同的是,它的参数不是一个,而是可以变化的。显然这种方式更加人性化。
事实上底层维护的就是一个数组,只是长度在运行期才确定

package tony.javacore.object.method.overload;

import static tony.javacore.util.io.IOUtils.println;

/** * 重载的可变参数 * * @author tony [email protected] * @file OverloadingVarArgs.java * @version 2016年2月6日下午6:38:51 * @since JDK7u80 */
public class OverloadingVarArgs {

    public static void printArray(Object... args) {

        println("execute method printArray(Object ...args)");
        for (Object obj : args) {
            println(obj);
        }
    }

    public static void printArray(int required, Object... args) {
        println("execute method printArray(int required,Object...args)");
    }

    public static void main(String[] args) {
        printArray(new Object[] { 1, 2, "3", '4', 5.0, 5.0f, false });

        printArray();// 不传递参数也是OK的

        printArray(1, new Object[] { "content", 12 });
    }

}

如果使用了可变参数的重载,必须要添加一个非可变参数。

你可能感兴趣的:(深入理解面向对象(二))