java面向对象(2)

1、基本数据类型的包装类

    java提供了8种基本数据类型的包装类类型:Byte、Short、Character、Integer、Long、Float、Double、Boolean,他们的基类都是Number,可以将他们与基本数据类型直接进行操作。

    两个包装类对象进行比较操作的话结果可能不是准确的,应该使用静态方法compare()来比较两个包装类对象,两个数相等返回0,第一个数大于第二个数返回1,小于返回-1。

    这8种包装类都提供public方法toString()和静态方法valueOf(),toString()将本对象转换为一个字符串,valueOf()接收一个对应的基本类型或String类型,返回一个包装类对象。String也包含valueOf()静态方法,所以使用valueOf()就可以完成数值和字符串之间的互换。

class Test  
{  
    public static void main(String[] args)  
    {  
          
        Integer iObj = 10;   
        Double fObj = 3.14 * iObj;  
        if(fObj > 3.14)  
            System.out.println(fObj); //输出31.40000000000002  
          
        Object obj = iObj;  
        if(obj instanceof Integer)  
        {  
            Integer inObj = (Integer)obj;  
            System.out.println(Integer.compare(iObj, inObj)); //输出为0  
        }  
          
		  
		//signed转换为unsigned
		long l = Integer.toUnsignedLong(-1000);//转换为无符号整数  
        String str = Integer.toUnsignedString(-1000); //转换为无符号整数后再转换为字符串  
        int i = Integer.divideUnsigned(-1000, -30); //将两个数转换为无符号后计算他们的商  
		  
		  
        //String和数值之间的转换  
        double d = Double.valueOf("3.14");  
		fObj = Double.valueOf(str);
		
		str = String.valueOf(3.14);
		str = String.valueOf(fObj);
		str = fObj.toString();
		str = fObj + "";
          
          
        //浮点型格式化转换为String  
        d = 13.615926;  
        str = new java.text.DecimalFormat("#").format(d); // "14",保留整数位  
        str = new java.text.DecimalFormat("#.00").format(d); // "13.62",保留两位小数  
        str = new java.text.DecimalFormat("000.00").format(d); // "013.62",保留三位整数位数  
        str = new java.text.DecimalFormat("#.00%").format(d); // "1361.59%",转为百分比  
        str = new java.text.DecimalFormat("#.00E0").format(d); // ".136E2",转为科学技术法  
    }  
}  

2、Object

    Object是类、数组、枚举类的父类,所以所有类型的对象都可以赋给Object类型变量,Object中部分成员函数:

        toString():返回"类名+@+hashCode"样式的字符串。当使用System.out.println()来输出一个对象的时候系统会自动调用对象的toString()方法。很多类都重写了Object的toString()方法,用于返回可表示该对象信息的字符串。

        equals():判断指定对象是否与自己相等,即两个对象是否为同一对象。

      hashCode():返回该对象的hashCode值,默认情况下对象的hash值是根据对象的地址来计算的,类似System的identityHashCode()方法。但很多类重写了该方法,比如String的hashCode()是以字符串内容来计算hash值。

        getClass():获得运行时的类,与对应类的静态成员class意义相同。

        finalize():当没有变量引用该对象后,垃圾回收机制调用该函数来清理对象的资源。

        ==:判断两个引用变量是否指向同一对象,如下所示,判断两个String的字符串内容是否相同的话应该使用equals()方法:

		Object o1 = "abc";
		Object o2 = "abc";
		Object o3 = new String("abc");
		Object o4 = new String("abc");
		
		System.out.println(o1 == o2); //true
		System.out.println(o3 == o4); //false
		System.out.println(o1 == o3); //false
		
		String s1 = "abc";
		String s2 = "abc";
		String s3 = new String("abc");
		String s4 = new String("abc");
		System.out.println(s1 == s2); //true
		System.out.println(s3 == s4); //false
		System.out.println(s1 == s3); //false

        clone();该方法获得当前对象的一个副本,它是浅克隆,即简单复制对象里的变量。clone()的效率很高,比如对于数组,clone比使用Arrays的静态方法copyOf()或System的静态方法arraycopy()来复制数组要快近两倍。因为clone()是protected类型,只能被子类调用或重写,所以我们一般是在自己在该方法中调用clone()方法,如:

class CFoo implements Cloneable //Cloneable为一个标记性的接口,该接口没有定义任何方法。
{
	public CFoo clone()throws CloneNotSupportedException
	{
		return (CFoo)super.clone();
	}
}
    Object还提供了wait()、notify()等线程控制方法。

    Object类的对象都可以与字符串进行+运算,相当于toString()后与字符相加:

		Test t = new Test();
		System.out.println(t.toString()); //输出Test@61064425
		System.out.println(t); //同样输出Test@61064425,直接输出对象相当于调用toString()输出
		
		System.out.println(t + "end"); //输出Test@61064425end

    因为所有的对象都派生自Object,所以我们可以在自己的类中重写Object的部分成员函数以实现自己的方法。如String类重写了toString()、equals()方法,equals()判断的是两个String中内容是否相等,==判断的是两个String是否指向同一对象,我们也可以实现自己类的equals:

public class Test
{
	public String name;
	public boolean equals(Object obj)
	{
		if(obj == this) //指向同一对象
			return true;
		if(obj != null && obj.getClass() == Test.class) //同一类型
		{
			Test t = (Test)obj;
			if(t.name.equals(name)) //成员name值相同
				return true;
		}
		return false;
	}
	public static void main(String[] args)
	{
		String str1 = "test";
		String str2 = new String("test");
		System.out.println(str1 == str2); //输出false
		System.out.println(str1.equals(str2)); //输出true
	}
}

3、Objects

类似Arrays,Objects工具类提供了一些方法来操作对象,而且这些方法大都是“空指针”安全的,比如对于一个值为null的引用变量来调用toString()的话会引发NullPointerExcetpion异常,而使用Objects则会返回"null",如:

public class Test
{
	static Test obj;
	public static void main(String[] args)
	{
		Objects.toString(obj); //输出为null
		Objects.hashCode(obj); //输出为0
		Objects.requireNonNull(obj, "obj为null"); //引发异常,输出信息"obj为null",requireNonNull的参数不为null则返回参数对象本身,否则引发异常。
	}
}

4、final

    final修饰变量的时候表示该变量一旦获得了初始值就不能再改变。
    final修饰的成员变量必须显示的指定初始值。
    final修饰引用类型变量的时候初始值不能改变指的是引用指向的对象不能改变,而该对象final修饰引用类型变量的时候初始值不能改变指的是引用指向的对象不能改变,而该对象的内容可以改变。

    final修饰的变量在定义的时候就直接初始化,而且初始化的值在编译的时候就可以确定下来的话,那这个变量就成为了“宏”:

	final int N = 5;
	final int NUM = 5 * 3;
	final String S = "Hello";
	final String STR = "Hello" + "World";
    final修饰方法表示该方法不能被子类重写。

    final修饰类表示该类不能被继承。

5、抽象类

    与c++类似,java中抽象类也不能实例化,只能用作父类,抽象类是子类的通用模板,子类可以在抽象类的基础上进行扩展改造,子类中只要有一个抽象方法没有重写(c++中纯虚函数)这个类就是一个抽象类。abstract用来声明抽象类和抽象方法,抽象类的构造函数主要用来被子类调用。因为抽象类就是用来继承的,所以声明抽象类后就不能再声明类为final类型。因为抽象类不能被实例化,所以抽象类中不能定义静态成员变量和静态方法。

    抽象类与多态的结合1, 父类对象调用子类方法:

abstract class AbsBase
{
	abstract void play();
}

class SubClass extends AbsBase
{
	void play(){ System.out.println("SubClass play"); }
}

class Foo
{
	private AbsBase b;
	public void func()
	{
		b = new SubClass();
		b.play(); //调用的是子类的play()函数:输出"SubClass play"
	}
}

    抽象类与多态的结合2,抽象类中普通方法调用子类中的方法(抽象方法推迟到子类去实现):

abstract class AbsBase
{
	abstract void play();
	void test()
	{
		play();
	}
}

class SubClass extends AbsBase
{
	void play(){ System.out.println("SubClass play"); }
}

class Foo
{
	private SubClass s;
	public void func()
	{
		s = new SubClass();
		s.test(); //test()中调用的是子类的play()方法
	}
}


猜你喜欢

转载自blog.csdn.net/milanleon/article/details/80337861