Java面向对象(七):Object类 & 内部类 & 单例模式
一、Object类
如果一个类没有继承任何类的话,默认继承Object 类,所以Object类为所有类的超类。
Object类常用的方法:
1、toString():返回该对象的字符串表示;
重写toString的意义:Object类中默认返回该对象的地址值字符串表示,没有太大的实际意义,若要知道类的成员信息或其他信息,则需要重写toString()方法,获取需要知道的信息;
2、equals():判断对象是否相等(重点能够手动重写);
重写equal()方法的意义:
Object类equals()默认根据比较两个对象的地址值相等(引用?)来判别对象是否相等;但是更多时候我们需要根据自己定义的条件来判定两个对象是否相等,一般情况下若两个同类对象的成员变量相等即判断两个对象是相等的,此时就需要重写equal()方法。
重写方式:
(1)自动(eclipse等IDE);
(2)手动
备注:
1、== 与equals区别:都是比较地址值,==数值型数据的共享性,equals直接比较地址值。
2、重写equals必须重写hashCode();
参考:http://www.cnblogs.com/111testing/p/7062310.html
3、getClass(): 获取字节码,反射知识。
4、hashCode():
哈希值,以一定算法将其他类型数据换算成十进制数据;
思考:
为什么重写equals()必须得重写hashCode:
因为在Object类中,若两个对象equal()比较后相同,则hashCode必定相同,但当重写完equal()方法后,会出现两个对象equal相同但是hashCode却不一定相同,所以也需要重写hashCode使得两个对象equal()比较相同时hashCode也相同。
5、finalize():
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
例程:studyObject包:Student.java
1 package studyObject; 2 //默认继承Object类 3 public class Student { 4 String name; 5 int age; 6 7 public Student(String name, int age) { 8 super(); 9 this.name = name; 10 this.age = age; 11 } 12 13 /* 14 * 重写toString意义: 15 * 若重写Object类中打印的是类的所属位置和类地址,没有太大意义 16 * 重写可打印出我们想要的东西 17 */ 18 @Override //注解,验证下面的方法是否是重写方法 19 public String toString() { 20 return " [姓名=" + name + ", 年龄=" + age + "]"; 21 } 22 23 //重写hashCode使得成员变量相等的同类对象哈希值也相同 24 @Override 25 public int hashCode() { 26 final int prime = 31; 27 int result = 1; 28 result = prime * result + age; 29 result = prime * result + ((name == null) ? 0 : name.hashCode()); 30 return result; 31 } 32 33 /* 34 * @ Mark:重写equal()方法的步骤 35 */ 36 @Override 37 public boolean equals(Object obj) { 38 // 1、判断是否为同一对象 39 if (obj==this) { 40 return true; 41 } 42 43 // 2、判断比较对象是否为空值 44 if (obj==null) { 45 return false; 46 } 47 48 // 3、判断比较对象是否为同类对象,再判断是否满足两对象相等的条件,一般比较成员变量即可; 49 if (obj instanceof Student) { 50 // 若为同类对象向下转型 51 Student objStu = (Student) obj; 52 53 // 判断相等的条件 54 if ( (objStu.age == age) && (objStu.name.equals(name)) ) { 55 return true; 56 } 57 } 58 59 return false; 60 } 61 62 /**自动重写 63 //重写equals 64 @Override 65 public boolean equals(Object obj) { 66 if (this == obj) 67 return true; 68 if (obj == null) 69 return false; 70 if (getClass() != obj.getClass()) 71 return false; 72 ObjectDemo1 other = (ObjectDemo1) obj; 73 if (age != other.age) 74 return false; 75 if (name == null) { 76 if (other.name != null) 77 return false; 78 } else if (!name.equals(other.name)) 79 return false; 80 return true; 81 } 82 ***/ 83 84 }
package studyObject; public class TextStudent { public static void main(String[] args) { Student OD1 = new Student("鲁班七号",3); Student OD2 = new Student("鲁班七号",3); //调用重写的toString方法 System.out.println("toString测试"+OD1); System.out.println("OD1哈希值:"+OD1.hashCode()); System.out.println("OD2哈希值:"+OD2.hashCode()); //调用重写的equals方法 System.out.println("equals测试变量值:" +( OD1.equals(OD2) ? "OD1与OD2相等": "OD1与OD2不相等") ); //比较地址值 System.out.println("OD1、OD2引用地址值:" +( OD1 == OD2 ? "OD1与OD2相等": "OD1与OD2不相等") ); } }
二、内部类
2.1 内部类:
在一个类中再定义一个类,外层类称为外部类,内层了称为内部类,内部类能够调用外部类的一切包括私有变量方法,
内部类只能够被外部类调用。
例程:
1 public class Outer { 2 private int time; 3 private Inner inner; 4 public Outer(int time) { 5 this.time=time; 6 inner=new Inner();//对象中会有一个隐式的引用指向创建它的Outer类对象。 7 inner.innerTime(); 8 9 } 10 public void printTime(){ 11 System.out.println(time);//101 12 } 13 //内部类 14 class Inner{ 15 //Inner类可以访问Outer类中的一切 16 public int innerTime(){ 17 return time++;//可以访问Outer的私有属性 18 } 19 } 20 public static void main(String[] args) { 21 Outer outer=new Outer(100); 22 outer.printTime(); 23 } 24 }
2.2 匿名内部类(掌握)
创建对象之执行依次
1、语法:
SuperType obj = new SuperType() {
匿名类的成员变量方法。
}
2、例程:
1 package interClass; 2 3 import java.util.Timer; 4 import java.util.TimerTask; 5 6 /**** 7 * 匿名内部类 8 * 9 * @author 89869 10 * 11 */ 12 public interface NiMingNeiBuLei { 13 public static void main(String[] args) { 14 Timer timer = new Timer(); 15 // 创建匿名内部类 16 TimerTask task= new TimerTask() { 17 @Override 18 public void run() { 19 // TODO Auto-generated method stub 20 System.out.println("支付宝到账100000万"); 21 } 22 }; 23 timer.schedule(task, 1, 3); 24 } 25 26 }
三、单例模式Singleton
Singleton:一个类只能创建一个对象
创建单例模式的两种方式
1 懒汉式(常用的):
1 package studySingleton; 2 /** 3 * 单例模式:类只有一个实例对象,其他类只能调用这个类的唯一对象不能再创建对象 4 * @author 89869 5 * 6 */ 7 8 public class SingletonDemo { 9 //懒汉式 10 private static SingletonDemo singleton =null; 11 12 //将构造函数设为私有使得其不能再其他地方创建对象 13 private SingletonDemo() { 14 15 } 16 public SingletonDemo getSingleton() { 17 if (singleton ==null ) { 18 singleton = new SingletonDemo(); 19 } 20 return singleton; 21 } 22 23 24 }
2、饿汉式:
1 package studySingleton; 2 /*** 3 * 单例模式:饿汉式 4 * @author 89869 5 * 6 */ 7 public class SingletonDemo2 { 8 private SingletonDemo2 singleton = new SingletonDemo2(); 9 10 private SingletonDemo2() { 11 super(); 12 // TODO Auto-generated constructor stub 13 } 14 15 public SingletonDemo2 getSingleton() { 16 17 return singleton; 18 } 19 }