Day 08 面向对象

Day08 面向对象

——多态、Object类

4.9 多态

定义:某一类事物的多种存在形态
例:动物中猫、狗。
猫这个对象对应的类型是猫类型。 猫 x = new 猫();
同时猫也是动物中的一种,也可以把猫成为动物。
动物 y = new 猫();
动物是猫和狗具体事务中抽取出来的父类型。
父类型引用指向了子类对象。
1.多态的体现 父类的引用指向了自己的子类对象。父类的引用也可以接收自己的引用对象。
2.多态的前提 必须是类与类之间有关系,要么继承,要么实现,存在覆盖。
3.多态的好处 多态的出现,大大提高了程序的扩展性。扩展性:前期预先调用功能,后期定义子类去实现功能,把子类作为参数传递进来实现后期扩展性。
4.多态的弊端 提高了扩展性,但是只能使用父类中的引用访问父类中的成员。
5.多态的应用
6.多态中成员函数的特点(多态使用的注意事项)
动物:猫、狗

abstract class Animal
{
	public abstract void eat();//吃这个不确定,使用抽象
	
}

class Cat extends Animal
{
	public void eat()
	{
		System.out.println("eat fish");
	}
	public void catchMouse()
	{
		System.out.println("catch Mouse");
	}
}

class Dog extends Animal
{
	public void eat()
	{
		System.out.println("eat meat");
	}
	public void bark()
	{
		System.out.println("bark");
	}
}

class Pig extends Animal
{
	public void eat()
	{
		System.out.print("eat siliao");
	}
	public void sleep()
	{
		System.out.println("sleep");
	}
}

class  duotai
{
	public static void main(String[] args) 
	{
		//Cat c = new Cat();
		//c.eat();

		//Dog d = new Dog();
		//d.eat();

		//Cat c = new Cat();
		//c.eat();
		//Cat c1 = new Cat();
		//c1.eat();

		//Cat c = new Cat();
		/*
		Cat c1 = new Cat();
		function(c1);
		function(new Dog());
		function(new Pig());
		*/
		//Animal c = new Cat();
		//c.eat();

		function(new Cat());
		function(new Dog());
		function(new Pig());
	}
	public static void function(Animal a)//Animal a = new Cat();
	{
		a.eat();
	}
	/*
	public static void function(Cat c)
	//本类类型接收本类对象,Cat c = new Cat();
	{
		c.eat();;
	}
	public static void function(Dog d)//function不用改,重载
	{
		d.eat();;
	}
	public static void function(Pig p)
	{
		p.eat();;
	}
	*/
}

转型
在这里插入图片描述

abstract class Animal
{
	public abstract void eat();//吃这个不确定,使用抽象
	
}

class Cat extends Animal
{
	public void eat()
	{
		System.out.println("eat fish");
	}
	public void catchMouse()
	{
		System.out.println("catch Mouse");
	}
}

class Dog extends Animal
{
	public void eat()
	{
		System.out.println("eat meat");
	}
	public void bark()
	{
		System.out.println("bark");
	}
}

class Pig extends Animal
{
	public void eat()
	{
		System.out.print("eat siliao");
	}
	public void sleep()
	{
		System.out.println("sleep");
	}
}

class  duotai
{
	public static void main(String[] args) 
	{
		//Animal a = new Cat();//类型提升,向上转型
		//a.eat();
		//如果想要调用猫的特有方法时,如何操作
		//强制将父类的引用转成子类类型,向下转型。
		//Cat c = (Cat)a;
		//c.catchMouse();
		//这种写法不允许,将父类对象转成子类类型
		//我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。
		//多态自始至终都是子类对象在做着变化。
		//Animal a = new Animal();
		//Cat c = (Cat)a;
		function(new Dog());
		function(new Cat());
	}
	public static void function(Animal a)//Animal a = new Cat();
	{
		a.eat();
		/*
		if(a instanceof Animal)//不要把父类型的判断放在前面
		{
			System.out.println("haha");
		}
		else 
		*/
		if (a instanceof Cat)
		{
			Cat c = (Cat)a;
			c.catchMouse();
		}
		else if (a instanceof Dog)
		{
			Dog c= (Dog)a;
			c.bark();
		}
	}	
}


在这里插入图片描述
多态示例
多态将对象调用这件事变简化,以前指挥每一个对象做事情,现在是可以指挥一批对象做事情,因为找到这些对象的共同所属类型。把对象不断向上抽象,总能找到共同点,可以统一操作很多对象。
基础班学生:学习、睡觉
高级版同学:学习、睡觉

abstract class Student
{
	public abstract void study();
	public void sleep()
	{
		System.out.println("躺着睡");
	}
}
class DoStudent
{
	public void doSome(Student stu)
	{
		stu.study();
		stu.sleep();
	}
}

class BaseStudent extends Student
{
	public void study()
	{
		System.out.println("base study");
	}
	public void sleep()
	{
		System.out.println("坐着睡");//覆写
	}
}
class AdvStudent extends Student
{
	public void study()
	{
		System.out.println("adv study");
	}
}

class  duotai1
{
	public static void main(String[] args) 
	{
		/*
		BaseStudent bs = new BaseStudent();
		bs.study();
		bs.sleep();
		AdvStudent as = new AdvStudent();
		as.study();
		as.sleep();
		*/
		DoStudent ds = new DoStudent();
		ds.doSome(new BaseStudent());
		ds.doSome(new AdvStudent());
	}	
}

多态中成员函数的特点(非静态,只有非静态才有重写的特性)
多态中:父类有指向子类对象的时候,由本类指向本类对象不是多态
Fu f = new zi();
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败。
在编译时,看的是f这个引用型变量所属类Fu里是不是有调用的方法:
f.method1();–>有
f.method2();–>有
f.method3();–>没有,编译失败
在运行时期:参阅对象所属的类中是否有调用的方法。
在运行时,看的是new Zi()这个对象所属类:Zi,Zi中有没有method1,method2,有就运行自己的,没有就找父类中的。
总结:成员函数在多态调用时,编译看左边,运行看右边。
面试:
1.在多态中,静态成员函数的特点:无论编译和运行,都参考左边。
2.在多态中,成员变量的特点:无论编译和运行,都参考左边(引用型变量所属的类)。

父类和子类,有相同名称的成员变量,这两个变量也是静态的,多态时,打印结果:父类。
静态绑定的是静态绑定,非静态绑定的是动态绑定。

class Fu
{
	static int num = 5;
	void method1()
	{
		System.out.println("fu method_1");
	}
	void method2()
	{
		System.out.println("fu method_2");
	}
	static void method4()
	{
		System.out.println("fu method_4");
	}
}

class Zi extends Fu
{
	static int num = 8;
	void method1()
	{
		System.out.println("zi method_1");
	}
	void method3()
	{
		System.out.println("zi method_3");
	}
	static void method4()
	{
		System.out.println("zi method_4");
	}
}

class  duotai3
{
	public static void main(String[] args) 
	{
		Fu f = new Zi();
		//f.method4();
		System.out,println(f.num);//静态只看引用所属,那个类 5
		//静态覆盖静态,结果 fu method_4,只有非静态才有重写功能
		Zi z = new Zi();
		z.method4();//结果 zi method_4
		
		//Fu f = new Zi();
		//System.out.println(f.num);//-->5
		//Zi z = new Zi();
		//System.out.println(z.num);//-->8
//在多态中,成员变量的特点:无论编译和运行,都参考左边(引用型变量所属的类)。
		
		//Fu f = new Zi();
		//f.method1();
		//f.method2();
		//f.method3();
		
		/*
		Zi z = new Zi();
		z.method1();
		z.method2();
		z.method3();
	-->	zi method_1//子类中把父类覆盖
		fu method_2//子类继承
		zi method_3//子类特有
		*/
	}
}

多态的主板示例
需求:电脑运行实例。电脑运行基于主板。
在这里插入图片描述

/*
class MainBoard
{
	public void run()
	{
		System.out.println("mainboard run");
	}
	public void useNetCard(NetCard c)
	{
		c.open();
		c.close();
	}
}
class NetCard
{
	public void open()
	{
		System.out.println("netcard open");
	}
	public void close()
	{
		System.out.println("netcard close");
	}
}
*/

interface PCI
{
	public void open();
	public void close();
}

class MainBoard
{
	public void run()
	{
		System.out.println("mainboard run");
	}
	public void usePCI(PCI p)//PCI p = new NetCard();接口型引用指向自己的子类对象
	{
		if(p != null)
		{
			p.open();
			p.close();
		}
	}
}

class NetCard implements PCI 
{
	public void open()
	{
		System.out.println("netcard open");
	}
	public void close()
	{
		System.out.println("netcard close");
	}
}

class SoundCard implements PCI
{
	public void open()
	{
		System.out.println("SoundCard open");
	}
	public void close()
	{
		System.out.println("SoundCard close");
	}
}

class duotai4 
{
	public static void main(String[] args) 
	{
		MainBoard mb = new MainBoard();
		mb.run();
		mb.usePCI(null);
		mb.usePCI(new NetCard());
		mb.usePCI(new SoundCard());
	}
}

多态的扩展示例
需求:数据库操作。
1.连接数据库。JDBC Hibernate 2.操作数据库。 c create r read u update d delete 3.关闭数据库
在这里插入图片描述

interface UserInfoDao//data access object
{
	public void add(User user);
	public void delete(User user);

}

class UserInfoByJDBC implements UserInfoDao
{
	public void add(User user)
	{
		1.JDBC连接数据库
		2.使用sql添加语句添加数据库
		3.关闭连接
	}
	public void delete(User user)
	{
		1.JDBC连接数据库
		2.使用sql删除语句删除数据库
		3.关闭连接
	}
}

class UserInfoByHibernate implements UserInfoDao
{
	public void add(User user)
	{
		1.Hibernate连接数据库
		2.使用sql添加语句添加数据库
		3.关闭连接
	}
	public void delete(User user)
	{
		1.Hibernate连接数据库
		2.使用sql删除语句删除数据库
		3.关闭连接
}


class  DBOperate
{
	public static void main(String[] args) 
	{
		//UserInfoByJDBC ui = new UserInfoByJDBC();
		//UserInfoByHibernate ui = new UserInfoByHibernate();
		UserInfoDao ui = new UserInfoByJDBC();
		ui.add(user);
		ui.delete(user);
	}
}

Object类——equals()
equals(Object obj) 指示其他某个对象是狗与此对象“相等”。
Object:是所有对象的直接或者间接父类,传说中的上帝。该类中定义的肯定是多有对象都具备的功能。
Object类中已经提供了对对象是否相同的比较方法。如果自定义类中有比较相同的功能,没有必要重新定义。只要沿袭父类中的功能,建立自己特有比较的内容即可。这就是覆盖。

class Demo//extends Object
{
	/*
	Demo()
	{
		super();
	}
	*/
	private int num;
	Demo(int num)
	{
		this.num = num;
	}
	public boolean equals (Object obj)//复写,覆盖 
	//Object obj = new Demo();
	//多态,父类指向子类对象,当想使用子类中特有内容,向下转型
	{
		if(!(obj instanceof Demo))//判断
			return false;
		Demo d = (Demo)obj;//转换
		return this.num == d.num;
	}

	//public boolean equals (Demo d)//重载,参数类型不同
	/*
	public boolean compare(Demo d)
	{
		return.this.num == d.num;
	}
	*/
	public String toString()
	{
		return "demo:" + num;//-->demo:4
	}
}

class  ObjectDemo
{
	public static void main(String[] args) 
	{
		/*
		Demo d1 = new Demo();
		Demo d2 = new Demo();
		Demo d3 = d1;	
		//equals 指示其他某个对象是否与此对象“相等”
		System.out.println(d1.equals(d2));//-->false,null时比较的地址值
		System.out.println(d1.equals(d3));//-->true
		System.out.println(d1 == d2);//-->false
		System.out.println(d1 == d3);//-->true
		*/
		Demo d1 = new Demo(4);
		Demo d2 = new Demo(6);
		System.out.println(d1.equals(d2));
		
		//System.out.println(d1.compare(d2));
		 System.out.println(d1.toString());
	}
}

Object类——toString()
toString() 返回该对象的字符串表示。= getClass().getName() + ‘@’ + IntegertoHexString(hashCode())
Demo d1 = new Demo(4);
System.out.println(d1.toString());
–>Demo@15db9742
Demo:对象所属类; @右边:对象的内存地址 hashCode

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值