J6-1 Object类

1.Object类

1.1概念

  • 在java中Object类是所有java类的根基类,是所有类的老祖宗
  • 如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类,例如
public class Persion{
}
//等价于
public class Persion extends Object{
}

1.2Object类中的方法

  • Object类中提供的方法有如下几个

  • toString()方法,默认返回类名加一个哈希值,其内部实现方法如下.建议所有子类重写该方法
getClass().getName() + '@' + Integer.toHexString(hashCode())
package com.hanqi.demo1;

class Dog{
	
}
public class test07 {

	public static void main(String[] args) {
		Dog d = new Dog();
		System.out.println("d:=" + d.toString());
		System.out.println("d:=" + d);
	}
}
///
d:=com.hanqi.demo1.Dog@15db9742
d:=com.hanqi.demo1.Dog@15db9742
    
/*重写toString方法之后*/
package com.hanqi.demo1;

class Dog{
	public String toString() {
		return "This is dog man";
	}
}
public class test07 {

	public static void main(String[] args) {
		Dog d = new Dog();
		System.out.println("d:=" + d.toString());
		System.out.println("d:=" + d);
	}
}
///
d:=This is dog man
d:=This is dog man
  • equals()方法,我们基于同一个类创建了2个对象,使用==后发现二者不一样,因为下述c1与c2存放的是指向堆内存的地址,明显不一样.那么如何来判断指向堆内存的东西是一样的呢?使用equals方法比较堆内存的东西是否一样,然神奇地发现equals==效果差不多.自此我们对Object类中的equals方法十分不满,因此我们要重写之.注意java的包里面有些类已经实现了equals方法,如String类里面就实现了equals方法
package com.hanqi.demo1;

class Cat{
	int color;
	int height, weight;
}
public class test07 {
	public static void main(String[] args) {
		Cat c1 = new Cat();
		Cat c2 = new Cat();
		System.out.println(c1 == c2);
	}
}
///
false

/*-------------------------------------------------------------------------------------------------*/
package com.hanqi.demo1;

class Cat{
	int color;
	int height, weight;
}
public class test07 {
	public static void main(String[] args) {
		Cat c1 = new Cat();
		Cat c2 = new Cat();
		System.out.println(c1.equals(c2));
	}
}
///
false
    
/*-------------------------------------重写后-------------------------------------------------------*/

package com.hanqi.demo1;

class Cat{
	int color;
	int height, weight;
	public Cat(int color, int height, int weight) {
		this.color = color;
		this.height = height;
		this.weight = weight;
	}
	public boolean equals(Object obj) {
		if(obj == null) 
		{
			return false;
		}
		else 
		{
			if(obj instanceof Cat) 
			{
				Cat c = (Cat)obj;
				if(c.color == this.color && c.height == this.height && c.weight == this.weight) 
				{
					return true;
				}
			}
		}
		return false;
	}
}
public class test07 {
	public static void main(String[] args) {
		Cat c1 = new Cat(1, 2, 3);
		Cat c2 = new Cat(1, 2, 3);
		System.out.println(c1.equals(c2));
	}
}
///
true

2.对象转型

2.1概念

  • 一个父类的引用类型变量可以"指向"其子类对象
  • 一个父类的引用不可以访问其子类对象新增加的成员(属性和方法)
  • 可以使用引用 变量 instanceof 类名来判断该引用型变量所"指向"的对象是否属于该类或者该类的子类

a instanceof Animal即a属于Animal类吗,a是动物吗?

  • 子类的对象可以当作基类的对象来使用称为向上转型(upcasting),反之为向下转型(downcasting)
package com.hanqi.demo1;

class Animal{
	public String name;
	public Animal(String name) {
		this.name = name;
	}
}
class Cat extends Animal{
	public String eyesColor;
	public Cat(String n, String c) {
		super(n);		//调用父类构造方法
		eyesColor = c;
	}
}
class Dog extends Animal{
	public String furColor;
	public Dog(String n, String c) {
		super(n);		//调用父类构造方法
		furColor = c;
	}
}
public class test07 {
	public static void main(String[] args) {
		Animal a = new Animal("name");
		Cat c = new Cat("catname", "blue");
		Dog d = new Dog("dogname", "black");
		System.out.println(a instanceof Animal);		//true
		System.out.println(c instanceof Animal);		//true
		System.out.println(d instanceof Animal);		//true
		System.out.println(a instanceof Cat);			//false
		
        /*此刻的a指向了Dog对象,但a原来是指向Animal对象的,而Dog对象内部又存在Animal对象(Dog继承自Animal),所以a只能访问到Dog内部属于Animal父类的成员*/
		a = new Dog("bigyellow", "yellow");
		System.out.println(a.name);						//bigyellow
		//System.out.println(a.furColor);				//error!!!!
		System.out.println(a instanceof Animal);		//true
		System.out.println(a instanceof Dog);			//true
		
        /*如果非得要a能访问Dog类的私有成员furColor,则需要将a强制转换为Dog类*/
		Dog d1 = (Dog)a;								//强制类型转换
		System.out.println(d1.furColor);				//yellow
	}
}

3.动态绑定和多态

3.1概念

  • 动态绑定是指"在执行期间(非编译期间)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法
  • 例如,下述实例中有2中动物均继承自Animal类
package com.hanqi.demo1;

class Animal{
	public String name;
	public Animal(String name) {
		this.name = name;
	}
	public void enjoy() {
		System.out.println("x叫声,xx...");
	}
}
class Cat extends Animal{
	private String eyesColor;
	public Cat(String n, String c) {
		super(n);
		eyesColor = c;
	}
	public void enjoy() {
		System.out.println("猫叫声,喵喵...");
	}
}
class Dog extends Animal{
	private String furColor;
	public Dog(String n, String c) {
		super(n);
		furColor = c;
	}
	public void enjoy() {
		System.out.println("狗叫声,汪汪...");
	}
}
/*
class Bird extends Animal{
	private String featherColor;
	public Bird(String n, String f) {
		super(n);
		featherColor = f;
	}
	public void enjoy() {
		System.out.println("鸟叫声,啾啾...");
	}
}*/
class Lady{
	private String name;
	private Animal pet;
	public Lady(String name, Animal pet) {
		this.name = name;
		this.pet = pet;
	}
	public void myPetEnjoy() {
		pet.enjoy();
	}
}
public class test07 {
	public static void main(String[] args) {
		Cat c = new Cat("mimi", "blue");
		Dog d = new Dog("tom", "black");
		//Bird b = new Bird("jiujiu", "yellow");
		Lady l1 = new Lady("l1", c);
		Lady l2 = new Lady("l2", d);
		//Lady l3 = new Lady("l3", b);
		l1.myPetEnjoy();
		l2.myPetEnjoy();
		//l3.myPetEnjoy();
	}
}

分析:我们new了一只猫和一个人,在人里面有一个成员为Animal对象,我们将其指向了new出来的cat,实际上cat继承自Animal.所以按理来讲人内部只能看见cat对象中属于Animal的那部分成员,即name,此时不能访问Cat的成员变量eyesColor.在代码中我们访问的是Animal中的enjoy方法,而方法存在于代码段,并且在上述代码中存在3种enjoy方法,最终执行结果是调用实际new对应的方法,即我们new的cat,就会调用cat中的enjoy方法.

好处:我们可以用少量代码实现极佳的可扩展性,例如当我们新建一个动物的时候直接new即可,然后给

posted @ 2021-08-05 23:33  MHDSG  阅读(72)  评论(0)    收藏  举报