12-20java面向对象之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类的所有方法(friendly和public)都能够使用。那么使用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 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
第一个例子Person继承equals 方法,没有重写,所以还是比较对象的引用是否相同,-->相同为true不相同falsep1,p2都是new创建的,在堆分配两块不同的空间,所以false
第二个例子obj1.equals(per1),比较的是obj1和per1,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类
Number是Object直接子类,他是将数字包装类中的内容变为基本数据类型(拆箱)。
装箱:将基本数据类型变为包装类
拆箱:将包装类变为基本数据类型
以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(); } }
祝大家健健康康,快快乐乐。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。