第6章 面向对象(下)(1)

1.Java8的增强包装类

自动装箱:可以把一个基本类型变量直接赋给对应的包装类变量,或者赋给Object变量(Object是所有类的父类,子类对象可以赋给父类变量)
自动拆箱:允许直接把包装类对象直接赋值给对应的基本类型变量。

String类型转基本类型有两种方式:

        int it1 = Integer.parseInt(intStr);
        int it2 = new Integer(intStr);

基本类型转Stirng类型有两种方式:

        String it = String.valueOf(5);
        String it3 = 5+"";

包装类型的实例可以与数值类型相比较
包装类型为整型(byte\short\int\long\char),相同基本类型值赋值给包装类型变量后,包装类型做“==”比较,在0-127范围内相等,因为有缓存。基本类型为float或double时,引用变量不相等。

2.处理对象

  • 打印对象和toString方法
    toString方法是Object类提供的实例方法,可以根据需要重写toString方法获取感兴趣的信息
Public String toString(){}
// 效果一样
System.out.println(obj);
System.out.println(obj.toString());

  • “==”:

在比较两个基础类型的变量时,只要求值相等即返回true,并不要求变量的类型完全相同。

在比较两个引用类型变量时,只有他们指向同一个对象,才返回true.

“equals()方法:”

equals()方法是Object类中的实例方法,但这个方法判断两个对象相等的标准与==没有区别,所以没有太大的实际意义,若想达到类似“值相等”的目的,则可采用重写equals方法实现:

String类已经重写了Object类的equals方法,String的equals()方法判断两个字符串相等的标准是:只要两个字符串所包含的字符串序列相同,则返回true。

    public boolean equals(Object obj) {
        return (this == obj);
    }

关于String的比较:

“hello”直接量与new String(“hello”)有什么区别?
当Java程序直接使用“hello”时,JVM将使用常量池管理这些字符串;当时用new String(“hello”)时,JVM先使用常量池管理“hello”直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象保存在堆内存中。换句话说,new String(“hello”)一共产生了两个字符串对象

String s1 = "疯狂Java";
        String s2 = "疯狂";
        String s3 = "Java";
        String s4 = "疯狂"+"Java";
        String s5 = "疯"+"狂"+"Java";
        String s6 = s2+s3;
        String s7 = new String("疯狂Java");

        System.out.println(s1 == s4);//true
        System.out.println(s1 == s5);//true
        System.out.println(s1 == s6);//false
        System.out.println(s1 == s7);//false

3.类成员

  • 理解类成员

对于staice关键字而言,有一条重要规则:类成员(包括方法、初始化块、内部类、枚举类)不能访问实例成员(包括方法、初始化块、内部类、枚举类)。

  • 单例(Singleton)类

一个类只能创建一个实例,该类被称为单例类。

几个注意的地方:
1. 构造器应该用private修饰(因为不能任意创建类的实例)
2. 应提供public static修饰的方法(本着良好封装的原则,应提供public方法用于创建类的实例,应该用static修饰(因为创建该对象的时候还没有对象))
3. 应定义static类型成员变量,类型为单例类。用于判断该单例类的对象是否已存在。(因为该成员变量需要通过static方法访问,所以该成员变量需用static修饰)

package chapter6.three;

/**
 * Created by liudy on 16/8/30.
 */
//单例类:一个类始终有一个实例

class Singleton {
    //使用一个变量来缓存曾经创建的实例
    private static Singleton instance;

    //对构造器使用private修饰,隐藏该构造器
    private Singleton() {
        System.out.println("单例类的构造器");
    }

    //提供一个静态方法,用于返回Singleton实例
    //该方法可以加入自定义控制,保证只产生一个Singleton对象
    public static Singleton getInstance() {
        //如果instance为null,表明还不曾创建singleton对象
        //如果instance不为null,表明已经创建singleton对象
        //将不会重新创建新实例
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}


public class SingletonTest {
    /**
     * @param args
     */
    public static void main(String[] args) {
        //创建Singleton对象不能通过构造器
        //只能通过getInstance方法来得到实例
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        System.out.println(s1==s2);
    }

}

4.final修饰符

  • final成员变量

final修饰的成员变量必需由程序员显示的指定初始值(系统不会对final成员进行隐式初始化)

类变量:必需在静态初始化块或声明该类变量时指定初始值,而且只能在两个地方之一指定

实例变量:必需在非静态初始化块、声明该实例变量或构造器中指定初始值,而且只能在三个地方之一指定

  • final局部变量

既可以在定义时指定默认值,也可以不指定默认值。

  • final修饰基本类型变量和引用类型变量的区别

//基本类型变量要求不能被改变
//引用类型要求引用的地址不改变,即一直引用同一个对象,但这个对象完全可以发生改变

  • 可执行“宏替换”的final变量

“宏变量”的三个条件:
1. 使用final修饰
2. 定义该final变量时指定了初始值
3. 初始值在编译时就能被确定

final  int a = 5;
        //实际输出时直接为System.out.println(5);
        System.out.println(a);

public class StringJoinTest {
    public static void main(String[] args) {
        String s1 = "疯狂Java";
        String s2 = "疯狂"+"Java";
        System.out.println(s1==s2);//true

        String str1 = "疯狂";
        String str2 = "Java";
        String str3 = str1+str2;
        System.out.println(s1==str3);//false

        final String str4 = "疯狂";
        final String str5 = "Java";
        String str6 = str4+str5;
        System.out.println(s1==str6);//true

    }
}
  • final方法

不可被重写,可以被重载

  • final类

不可被继承

  • 不可变类

不可变类: 创建该类的实例后,该实例的实例变量是不可变的
Java提供的8个包装类和java.lang.String类都是不可变类

如果需要创建自定义的不可变类,可遵守如下规则:
1. 使用private和final修饰成员变量
2. 提供带参数构造器用来初始化成员变量
3. 仅为该类的成员变量提供getter方法,不要为该类提供setter方法,因为普通方法无法修改final修饰的成员变量。

final修饰基本类型变量和引用类型变量的区别
基本类型变量要求不能被改变
引用类型要求引用的地址不改变,即一直引用同一个对象,但这个对象完全可以发生改变

package chapter6.four;

/**
 * Created by liudy on 16/8/30.
 * 不可变类中包含引用类型变量
 */
class Name{
    private String firstName;
    private String lastName;

    public Name() {
    }

    public Name(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

//因为Human包含了一个引用类型的成员变量(Name类型),导致Human变成了一个可变类
public class Human {
    private  final  Name name;

    //下面的方式将导致Human类可变
//    public Human(Name name) {
//        this.name = name;
//    }
//
//    public Name getName() {
//        return name;
//    }
    public Human(Name name) {
        //设置name实例变量为临时创建的Name对象,该对象的firstName与lastName
        //与传入name对象的firstName与lastName相同
        this.name = new Name(name.getFirstName(),name.getLastName());
    }
    //返回一个匿名对象,该对象的firstName与lastName
    //与传入name对象的firstName与lastName相同
    public Name getName() {
        return new Name(name.getFirstName(),name.getLastName());
    }

    public static void main(String[] args) {
        Name n = new Name("悟空","孙");
        Human h = new Human(n);
        //获取Human对象的firstname值为"悟空"
        System.out.println(h.getName().getFirstName());
        n.setFirstName("八戒");
        //将打印"八戒"
        System.out.println(h.getName().getFirstName());
    }
}
  • 缓存实例的不可变类
    待整理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值