第十五章_Object类与对象类型判断

第十五章 Object类与对象类型判断


提纲

  • 15.1 Object类
    • 15.1.1 什么是Object类
    • 15.1.2 为什么没有extends Object关键字
    • 15.1.3 详解toString()和equals()方法
    • 15.1.4 clone()方法
  • 15.2 对象类型判断(instanceof)
    • 15.2.1 为什么要判断对象类型
    • 15.2.2 语法
    • 15.2.3 举例
    • 15.2.4 进阶题

15.1 Object类

  • 15.1.1 什么是Object类:在Java中,所有的类都直接或者间接的继承了java.lang.Object类。Object是一个比较特殊的类,它是所有类的父类,是Java类层中的最高层。当创建一个类时,总是在继承,除非这个类已经指定要从其他类继承,否则它就是从java.lang.Object类继承而来。

  • 15.1.2 为什么没有extends Object关键字呢?

      //创建一个Book类
      public class Book {
    
      }
      等价于
      public class Book extends Object{
      	
      }
      //因为每个类都直接或者间接的继承了Object类,所以省略了关键字
    
  • 15.1.3 详解toString()和equals()方法

    • toString()方法

      1. 含义:toString()方法的功能是将一个对象返回为字符串形式,它会返回一个String实例。实际应用中通常重写toString()方法。

      2. 举例:

         //这个是Object中的toString()方法
         public String toString() {
         	return getClass().getName() + "@" + Integer.toHexString(hashCode());
         }
         //将2中的Book调用toString()方法并打印
         public class Test {
         	public static void main(String[] args) {
         		Book book = new Book();
         		System.out.println(book);
         		System.out.println(book.toString());
         	}
         }
         //执行结果
         com.zxjy.day1010.Book@1bc4459
         com.zxjy.day1010.Book@1bc4459
        

      结论:当打印这个对象时会默认调用Object类中的toString()方法。
      3. 重写toString()方法

        	//创建一个Book类,类中有属性,并且重写toString()方法
        	public class Book{
        		String name;
        		@Override
        		public String toString() {
        			return "这是一本叫:"+name+"的书。";
        		}
        	}
        	//创建测试类,打印对象
        	public class Test {
        		public static void main(String[] args) {
        			Book book1 = new Book();
        			book1.name = "星辰变";
        			System.out.println(book1.toString());
        			Book book2 = new Book();
        			book2.name = "诛仙";
        			System.out.println(book2.toString());
        		}
        	}
        	//执行结果
        	这是一本叫:星辰变的书。
        	这是一本叫:诛仙的书。
      

      结论:当重写toString()方法后,调用对象toString()方法时会调用重写的toString()方法。

    • equals()方法与==的区别

      1. 创建一个字符串的两种形式

         //形式1:
         String str1 = "abc";
         String str2 = "abc";
         //形式2:
         String str3 = new String("abc");
         String str4 = new String("abc");
        

        区别(见图解:创建一个字符串的两种形式.jpg):1.如果“abc”这个字符串在内存中不存在,会在内存中创建一个创建一个String对象(“abc”),即new一个String对象。然后str1指向这个内存地址,无论以后用这种方式创建多少个值为”abc”的字符串对象,始终只有一个内存地址被分配,之后的都是String的拷贝,Java中称为“字符串驻留”。形式2.不论内容是否相等,都会在内存中开辟一个新的空间,来存放这个字符串。

      2. 给同一个字符串引用赋值

         String str = "abc";
         str = "def";
        

        过程解释(见图解:创建一个字符串的两种形式.jpg):首先创建了一个str字符串引用,对象为“abc”,当将“def”再次赋值给str引用时,str引用不再指向“abc”对象,而是重新指向“def”对象,原来的对象则没有引用指向,会在不确定的时候被垃圾回收机制回收掉。

      3. 两种比较的区别

         String str1 = "abc";
         String str2 = "abc";
         String str3 = new String("abc");
         String str4 = new String("abc");
         System.out.println("str1==str2的比较结果:"+(str1 == str2));
         System.out.println("str1.equals(str2))的比较结果:"+(str1.equals(str2)));
         System.out.println("str3==str4的比较结果:"+(str3 == str4));
         System.out.println("str3.equals(str4))的比较结果:"+(str3.equals(str4)));
         //执行结果
         str1==str2的比较结果:false
         str1.equals(str2))的比较结果:true
         str3==str4的比较结果:true
         str3.equals(str4))的比较结果:true
        

        结论:equals()比较的是内容是否相等,==比较的是内存地址是否相等,即是否是同一个对象。
        外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 15.1.4 clone()方法

    1. clone()方法的作用:clone()可以产生一个相同的类并且返回给调用者。
    2. clone()是如何工作的:Object将clone()作为一个本地方法来实现,这意味着它的代码存放在本地的库中。当代码执行的时候,将会检查调用对象的类(或者父类)是否实现了java.lang.Cloneable接口(Object类不实现Cloneable)。如果没有实现这个接口,clone()将会抛出一个检查异常()——java.lang.CloneNotSupportedException,如果实现了这个接口,clone()会创建一个新的对象,并将原来对象的内容复制到新对象,最后返回这个新对象的引用。
    3. 怎样调用clone()来克隆一个对象:用想要克隆的对象来调用clone(),将返回的对象从Object类转换到克隆的对象所属的类,赋给对象的引用。
      • 本类中克隆对象

          public class CloneDemo implements Cloneable{
          	String name;
          	int age;
          	
          	@Override
          	public String toString() {
          		return "CloneDemo [age=" + age + ", name=" + name + "]";
          	}
          
          	public static void main(String[] args) throws CloneNotSupportedException {
          		CloneDemo cd = new CloneDemo();
          		cd.name = "尼古拉斯.赵四";
          		cd.age = 100;
          		System.out.println("cd:"+cd);
          		CloneDemo cd2 = (CloneDemo) cd.clone();
          		System.out.println("cd2:"+cd2);
          	}
          }
          //执行结果
          cd:CloneDemo [age=100, name=尼古拉斯.赵四]
          cd2:CloneDemo [age=100, name=尼古拉斯.赵四]
        
      • 从别的类中克隆对象:上面的例子中,调用clone()的代码是位于被克隆的类(即CloneDemo类)里面的,所以就不需要覆盖clone()了。但是,如果调用别的类中的clone(),就需要覆盖clone()了。否则,将会看到“clone在Object中是被保护的”提示,因为clone()在Object中的权限是protected。(译者注:protected权限的成员在不同的包中,只有子类对象可以访问。代码清单3的CloneDemo类和代码清单4的Data类是Object类的子类,所以可以调用clone(),但是代码清单4中的CloneDemo类就不能直接调用Data父类的clone())。代码清单4在代码清单3上稍作修改来演示覆盖clone()。

          //创建CloneDemo类
          public class CloneDemo{
          	String name;
          	int age;
          	
          	public CloneDemo() {
          		
          	}
          	public CloneDemo(String name, int age) {
          		this.name = name;
          		this.age = age;
          	}
          	@Override
          	protected Object clone() throws CloneNotSupportedException {
          		return super.clone();
          	}
          	@Override
          	public String toString() {
          		return "CloneDemo [age=" + age + ", name=" + name + "]";
          	}
          }
          //测试类
          public class Test implements Cloneable{
          	public static void main(String[] args) throws CloneNotSupportedException {
          		CloneDemo cd = new CloneDemo();
          		cd.name = "尼古拉斯.凯奇";
          		cd.age = 888;
          		System.out.println("cd:"+cd);
          		CloneDemo cd2 = (CloneDemo) cd.clone();
          		System.out.println("cd2:"+cd2);
          	}
          }
          //执行结果
          cd:CloneDemo [age=888, name=尼古拉斯.凯奇]
          cd2:CloneDemo [age=888, name=尼古拉斯.凯奇]
        
      • 克隆基本类型数组和对象数组

          public class Test{
          	public static void main(String[] args) throws CloneNotSupportedException {
          		//克隆基本类型数组
          		double[] temps = {98.6, 32.0, 100.0, 212.0, 53.5};
          		System.out.print("temps:");
          		for (int i = 0; i < temps.length; i++) {
          			System.out.print("temps:"+temps[i]+" ");
          		}
          		System.out.println();
          		double[] temps2 = temps.clone();
          		System.out.print("temps2:");
          		for (int i = 0; i < temps2.length; i++) {
          			System.out.print("temps2:"+temps2[i]+" ");
          		}
          		System.out.println();
          		//克隆对象数组
          		CloneDemo[] cloneDemos = {new CloneDemo("AAAA", 18), new CloneDemo("BBBB", 10)};
          		System.out.print("cloneDemos:");
          		for (int i = 0; i < cloneDemos.length; i++) {
          			System.out.print("cloneDemos:"+cloneDemos[i]+" ");
          		}
          		System.out.println();
          		CloneDemo[] cloneDemos2 = cloneDemos.clone();
          		System.out.print("cloneDemos2:");
          		for (int i = 0; i < cloneDemos2.length; i++) {
          			System.out.print("cloneDemos2:"+cloneDemos2[i]+" ");
          		}
          	}
          }
          //执行结果
          temps:temps:98.6 temps:32.0 temps:100.0 temps:212.0 temps:53.5 
          temps2:temps2:98.6 temps2:32.0 temps2:100.0 temps2:212.0 temps2:53.5 
          cloneDemos:cloneDemos:CloneDemo [age=18, name=AAAA] cloneDemos:CloneDemo [age=10, name=BBBB] 
          cloneDemos2:cloneDemos2:CloneDemo [age=18, name=AAAA] cloneDemos2:CloneDemo [age=10, name=BBBB] 
        

15.2 对象类型判断(instanceof)

  • 15.2.1 为什么要判断对象类型:当向下转型时,如果父类的引用不是子类的实例,即两个对象之间不存在继承关系时就会出现异常。所以在转型时要事先判断父类是否为子类对象的实例。

  • 15.2.2 语法:某类对象的引用 instanceof 某个类

  • 15.2.3 举例:

      //创建动物类
      public class Animal {
    
      }
      //创建猫类继承动物类并重写toString()方法
      public class Cat extends Animal{
      	@Override
      	public String toString() {
      		return "这是一只猫";
      	}
      }
      //创建狗类继承动物类并重写toString()方法
      public class Dog extends Animal{
      	@Override
      	public String toString() {
      		return "这是一条狗";
      	}
      }
      //创建测试类测试
      public class Test {
      	public static void main(String[] args) {
      		Animal animal = new Cat();
      		//判断这个父类animal引用对象是否为子类Cat的对象
      		if (animal instanceof Cat) {
      			Cat cat = (Cat) animal;
      			System.out.println(cat);
      		}
      		if (animal instanceof Dog) {
      			Dog dog = (Dog) animal;
      			System.out.println(dog);
      		}
      	}
      }
      //执行结果
      这是一只猫
    
  • 15.2.4 进阶题:有动物类Animal,动物类有子类猫Cat和狗Dog。猫中有方法抓老鼠catchMice(),狗中有方法看门lookDoor()。使用随机数Random类,随机五次,如果随机出1,则创建一只猫,并存在对象数组中,如果随机出2,则创建一条狗,也存在同一个对象数组中。最后打印出对象数组的所有对象,并要求调用猫类和狗类中自己的方法。提示:1.每次随机的动物是未知的,所以数组中有猫还是狗是未知的。2.如果要调用子类中的方法必须创建子类的实例才可以,即向下转型,父类的引用指向子类的实例是无法调用子类自己的方法的。

      //创建动物类
      public class Animal {
    
      }
      //创建猫类继承动物类并有catchMice()方法
      public class Cat extends Animal{
      	public void catchMice(){
      		System.out.println("抓老鼠");
      	}
      }
      //创建狗类继承动物类并有lookDoor()方法
      public class Dog extends Animal{
      	public void lookDoor(){
      		System.out.println("狗看门");
      	}
      }
      //创建测试类测试
      public class Test {
      	public static void main(String[] args) {
      		Random random = new Random();
      		int num;
      		Animal[] animals = new Animal[5];
      		for (int i = 0; i < 5; i++) {
      			num = random.nextInt(2)+1;
      			if (num == 1) {
      				animals[i] = new Cat();
      				System.out.println("发现了一只猫!");
      			} else if (num == 2) {
      				animals[i] = new Dog();
      				System.out.println("发现了一条狗!");
      			}
      		}
      		for (int i = 0; i < animals.length; i++) {
      			if (animals[i] instanceof Cat) {
      				Cat cat = (Cat) animals[i];
      				cat.catchMice();
      			}
      			if (animals[i] instanceof Dog) {
      				Dog dog = (Dog) animals[i];
      				dog.lookDoor();
      			}
      		}
      	}
      }
      //执行结果
      发现了一只猫!
      发现了一只猫!
      发现了一条狗!
      发现了一条狗!
      发现了一条狗!
      抓老鼠
      抓老鼠
      狗看门
      狗看门
      狗看门
    

nstanceof Cat) {
Cat cat = (Cat) animals[i];
cat.catchMice();
}
if (animals[i] instanceof Dog) {
Dog dog = (Dog) animals[i];
dog.lookDoor();
}
}
}
}
//执行结果
发现了一只猫!
发现了一只猫!
发现了一条狗!
发现了一条狗!
发现了一条狗!
抓老鼠
抓老鼠
狗看门
狗看门
狗看门

  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值