12-20java面向对象之Object类&包装类&匿名内部类

1.Object类
在java的开发中,一切类都是以继承的方式存在的,如果一个类在定义时没有明确指明继承的是哪个类,那么默认情况继承Object类。

例如

class Person 
{
}

以上代码默认定义Object,其完整表达形式为:

class Person extends Object
{
}

jdk文档中,API-> index->java.lang->Object寻找Object类。

一个完整的类应该是覆写Object类的方法,下面主要讲解重要的方法。

1.1public String toString()

对象打印的时候调用。

例如

class Person			// 定义了Person类,实际就是继承了Object类
{
}
public class TestObject 
{
	public static void main(String[] args) 
	{
		Person per = new Person();
		System.out.println(per);
	}
}

结果打印的是per的地址

由于Person是继承了Object类,所以Object类的所有方法(friendlypublic)都能够使用。那么使用toString()

class Person			// 定义了Person类,实际就是继承了Object类
{
}
public class TestObject 
{
	public static void main(String[] args) 
	{
		Person per = new Person();
		System.out.println(per.toString());
	}
}

发现结果相同,那么说明在打印的时候一定会调用toString()方法,它是默认调用的。就可以用这个方法完成信息的输出。

class Person			// 定义了Person类,实际就是继承了Object类
{
	private String name ;
	private int age ;
	public Person(String name , int age)
	{
		this.name =name ;
		this.age = age;
	}
	public String toString()
	{
		return "姓名:" + this.name + ",年龄:" + this.age ;
	}
}
public class TestObject 
{
	public static void main(String[] args) 
	{
		Person per = new Person("Tyrion",24);
		System.out.println("使用toString()方法" + per.toString());
		System.out.println("不使用toString()方法" + per);
	}
}

所以今后要打印输出对象的信息时,直接覆写toString 方法,直接使用对象就可以打印。

1.2public boolean equals(Object obj)

equals()完成对象内容的比较,以前在String类中使用过。

class Person			// 定义了Person类,实际就是继承了Object类
{
	private String name ;
	private int age ;
	public Person(String name , int age)
	{
		this.name =name ;
		this.age = age;
	}
	public boolean equals(Object obj)
	{
		if (this == obj)	// 说明两个类占用一个地址
		{
			return true ;
		}
		if (obj instanceof Person)  	//必须保证是一个类才能进行比较,不能因为两个对象属性相同就比较
		{
			// Object是父类,这使用要比较父类中的属性,需要向下转型
			Person per = (Person) obj ;
			if (this.name.equals(per.name) && this.age == per.age)
			{
				return true ;
			}
			else 
			{
				return false ;
			}
		}else
		{
			return false ;
		}			
	}
	public String toString()
	{
		return "姓名:" + this.name + ",年龄:" + this.age ;
	}
}
public class TestObject 
{
	public static void main(String[] args) 
	{
		Person per1 = new Person("Tyrion",24);
		Person per2 = new Person("Tyrion",24);
		System.out.println(per1.equals(""));	
		System.out.println(per1.equals(per2));	
	}
}

程序注意:

覆写过程中,使用Object,由于Object是所有类的父类,所以首先要进行instanceof判断,之后还要进行向下转型,将Object类变为子类才能继续进行比较。

程序拓展:

这个程序是说明这么个问题——可以定义不同的子类(相对于Object而言),他们可能需要比较,则可以直接继承该方法。

但是问题来了:

class Person			// 定义了Person类,实际就是继承了Object类
{
	private String name ;
	private int age ;
	public Person(String name , int age)
	{
		this.name =name ;
		this.age = age;
	}	
}
public class TestObject 
{
	public static void main(String[] args) 
	{
		Person per1 = new Person("Tyrion",24);
		Person per2 = new Person("Tyrion",24);
		System.out.println(per1.equals(per2));	
	}
}
false

class Person			// 定义了Person类,实际就是继承了Object类
{
	private String name ;
	private int age ;
	public Person(String name , int age)
	{
		this.name =name ;
		this.age = age;
	}	
}
public class TestObject 
{
	public static void main(String[] args) 
	{
		Person per1 = new Person("Tyrion",24);
		Person per2 = new Person("Tyrion",34);
		Object obj1 = per1;
		Object obj2 = per2;
		System.out.println(obj1.equals(per1));	
	}
}
true

Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x  y,当且仅当 x  y 引用同一个对象时,此方法才返回 truex == y 具有值 true)。
第一个例子Person继承equals 方法,没有重写,所以还是比较对象的引用是否相同,-->相同为true不相同falsep1,p2都是new创建的,在堆分配两块不同的空间,所以false

第二个例子obj1.equals(per1),比较的是obj1per1,Object obj1 = per1;传递时把per1的值传递给obj1,所以两个对象指向同一块空间,返回true;

 

由于Object是所有类的父类,所有类的对象都可以使用Object进行接收,Object还可以接收任意的引用数据类型

 

使用Object进行接口接收

interface A
{
	public abstract String getInfo();
}
class B implements A			//B类实现接口A
{
	public String getInfo()
	{
		return "hello  world ";
	}
}
public class TestObject 
{
	public static void main(String[] args) 
	{
		A a = new B();		//实例化接口
		Object obj = a;	// 使用Object进行接收,向上转型
		A x = (A) obj;		//向下转型
		System.out.println(x.getInfo());
	}
}

使用Object进行数组接收

public class TestObject 
{
	public static void main(String[] args) 
	{
		int arr[] = {1,3,4,5};			//定义数组
		Object obj = arr;
		print(obj);
	}
	public static void print(Object obj)
	{
		if (obj instanceof int[])		//判断是否是整型数组
		{
			int x[] = (int[]) obj;		//向下转型,将对象转变为整型数组
			for (int i=0;i<x.length ;++i )
			{
				System.out.println(x[i]);
			}
		}
	}
}

1.3总结

1、 Object是所有类的父类,只要是引用数据类型都可以使用Object进行传递

2、 对象在向下转型之前一定要向上传递,并且要用instanceof判断

2.包装类

java中提出一种思想:一切皆对象。那么基本数据类型不是对象,把8种基本数据类型包装成类。

8种包装类

技术分享

对于Number

技术分享

NumberObject直接子类,他是将数字包装类中的内容变为基本数据类型(拆箱)。

装箱:将基本数据类型变为包装类

拆箱:将包装类变为基本数据类型

Integer为例:

public Integer(int value)

public class TestWapper1 
{
	public static void main(String[] args) 
	{
		Integer i = new Integer(11) ;		// Integer类的构造方法,相当于子类实例化,装箱
		Number num = i ;		     //向上传递
		int x = num.intValue();		// 调用Number类的方法,拆箱
	}
}

Float为例:

public class TestWapper2 
{
	public static void main(String[] args) 
	{
		Float f = new Float(11.1f) ;		// Float类的构造方法,相当于子类实例化,装箱
		float x = f.floatValue();		// 调用Number类的方法,拆箱
	}
}

JDK1.5之前,程序的包装类不能直接使用“+ - * /”,因为他们都是一个类。之后对包装类的功能进行了改变,增加了自动装箱和拆箱,而且也可以使用包装类进行数字运算。

public class TestWapper3 
{
	public static void main(String[] args) 
	{
		Integer i = 30 ;		//自动装箱成Integer
		int j = i ;				//自动拆箱成int
	}
}

在包装类中,存在对大的特点——把字符串变为指定的数据类型。

integer

parseInt

public static int parseInt(String s)                    throws NumberFormatException

parseFloat

public static int parseFloat(String s)                    throws NumberFormatException

该字符串必须由数字组成,该方法的特点——可以通过输入传递字符串。

public class TestWapper3 
{
	public static void main(String[] args) 
	{
		String str1 = "300" ;		//该字符串必须全是数字
		String str2 = "300.33" ;		//该字符串必须全是数字
		int i = Integer.parseInt(str1) ;
		float j = Float.parseFloat(str2);
		System.out.println("整数的乘方:" + i + "*" + i + "="+ i*i);
		System.out.println("小数的乘方:" + j + "*" + j + "="+ j*j);
	}
}

public class TestWapper3 
{
	public static void main(String[] args) 
	{
		String str1 = new String(args[0]) ;		//该字符串必须全是数字
		String str2 = new String(args[1]) ;		//该字符串必须全是数字
		int i = Integer.parseInt(str1) ;
		float j = Float.parseFloat(str2);
		System.out.println("整数的乘方:" + i + "*" + i + "="+ i*i);
		System.out.println("小数的乘方:" + j + "*" + j + "="+ j*j);
	}
}

2.匿名内部类

定义:一个类在整个操作中只是用一次,定义为匿名内部类,在抽象类和接口的基础之上发展过来。

interface  A
{
	public abstract void print();		//定义内部抽象方法
}
class B implements A
{
	public void print()
	{
		System.out.println("hello java");
	}
}
class C
{
	public void fun1()
	{
		this.fun2(new B());			//传一个B的实例,调用接口方法
	}
	public void fun2(A a)
	{
		a.print();
	}
}
public class noName_Inner 
{
	public static void main(String[] args) 
	{
		C c =new C();
		c.fun1();
	}
}

如果此时,B类只是用一次,那么就没有必要单独定义一个类了。

interface  A
{
	public abstract void print();		//定义内部抽象方法
}
class C
{
	public void fun1()
	{
		this.fun2(new A()
					{
						public void print()
						{
							System.out.println("hello java");
						}
					}
			);			//传一个B的实例,调用接口方法
	}
	public void fun2(A a)
	{
		a.print();
	}
}
public class noName_Inner2 
{
	public static void main(String[] args) 
	{
		C c =new C();
		c.fun1();
	}
}

祝大家健健康康,快快乐乐。









郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。