Java基础视频教程第08天_面向对象之多态

本文深入探讨面向对象编程中的多态概念,包括多态的定义、代码体现、转型应用、示例分析及主板示例。同时,阐述了多态在不同场景下的优势与局限性,并通过实例说明了如何利用多态简化对象调用,增强程序的扩展性和灵活性。此外,还详细介绍了多态中成员的特点,以及面向对象编程中Object类的equals()与toString()方法的使用。

一、面向对象——多态——概念

	1、概念:某一类事物的多种存在形态。
	例如:
		猫 m = new 猫();
		狗 n = new 狗();
		动物 a = new 猫();
		动物 a = new 狗();

	动物是猫和狗具体事物中抽取出来的父类型;
	这里父类引用指向了子类对象。

二、面向对象——多态——扩展性

1、多态的代码体现形式: 父类的引用指向了子类对象(父类的引用接收子类的对象)。 2、多态的前提: A、类与类之间存在关系——继承或者实现; B、存在覆盖。 3、多态的好处: 多态的出现大大的提高了程序的扩展性。 4、多态的弊端: 父类的引用只能访问父类中的成员。 示例:
	abstract class Animal
	{
		abstract void eat();
	}
	class Cat extends Animal
	{
		public void eat()
		{
			System.out.println("吃鱼");
		}
		public void catchMouse()
		{
			System.out.println("抓老鼠");
		}
	}
	class Dog extends Animal
	{
		public void eat()
		{
			System.out.println("吃骨头");
		}
		public void kanJia()
		{
			System.out.println("看家");
		}
	}
	class Pig extends Animal
	{
		public void eat()
		{
			System.out.println("饲料");
		}
		public void gongDi()
		{
			System.out.println("拱地");
		}
	}
	class DuoTaiDemo 
	{
		public static void main(String[] args) 
		{
			Animal c = new Cat();
			Animal d = new Dog();
			Animal p = new Pig();
			function(c);
			function(d);
			function(p);	
		}
		public static void function(Animal a)
		{
			a.eat();
			//a.catchMouse();//编译失败:因为父类中没有改方法,不能覆盖。
		}
	}

三、面向对象——多态——转型

1、向上转型:
当父类引用指向自己的子类对象时,将子类类型提升为父类类型。

2、向下转型:
当父类引用指向自己的子类对象时,将父类引用转成子类类型。

3、注意:
A、不能将父类对象转成子类类型。
B、只有当父类引用指向自己的子类对象时,才可以转型。
C、多态自始至终都是子类对象在做着变化。

4、 instanceof 的应用:
A、java 中的 instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。
instanceof 通过返回一个布尔值,来指出这个对象是否是这个特定类或者是它的子类的一个实例。(来自网络释义)

B、 instanceof 用于判断的两种情况:
①子类类型是有限的(比如:人分为男人的女人);
②当所传的类型需进行其他操作(比如比较的时候,需确定子类的类型来调用对应的方法)。

示例(接上例):
	public static void main(String[] args) 
	{
		Animal c = new Cat();//类型提升:向上转型;猫类型提升为动物类型。
		function(c);

		Cat c1 = (Cat)c;//向下转型:动物类型转型为猫类型。
		c1.catchMouse();

		//不可以将父类对象转成子类类型
		//Animal a = new Animal();
		//Cat c = (Cat)a;
	}
	public static void function(Animal a)//Animal a = new Dog();
	{
		a.eat();
		//Cat c = (Cat)a;//如果传进来的是狗,编译失败。
		//c.catchMouse();

		//修正后代码
		if (a instanceof Cat)
		{
			Cat c = (Cat)a;
			c.catchMouse();
		}
		else if (a instanceof Dog)
		{
			Dog d = (Dog)a;
			d.kanJia();
		}
		else
		{
			System.out.println("未知动物类型");
		}
	}

四、面向对象——多态——示例

需求:
基础班学生:
学习,睡觉。
高级班学生:
学习,睡觉。
但是基础班和高级班的学习内容和睡觉方式可能不一样。

可以将这两类事物进行抽取。

代码:
	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  DuoTaiDemo
	{
		public static void main(String[] args) //主函数是最终的调用者,由主函数调用工具类,让工具类去完成对应的功能。
		{
			DoStudent ds = new DoStudent();//建立功能对象
			ds.doSome(new BaseStudent());//调用功能对象的方法
			ds.doSome(new AdvStudent());
		}
	}
	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");
		}
	}

总结:多态将对象调用的事情变简单了。从指挥一个对象做事情变成指挥一批对象做事情,那是因为找到了这些对象的共同所属类型。

=====主函数一般作为最终调用者,也就是客户端;并建立好工具类,让工具类去完成相应的调用动作。

五、面向对象——多态中成员的特点

1、在多态中,非静态成员函数的特点:
在编译时期:编译能否通过,请参阅引用型变量所属的类中是否有调用的方法;
在运行时期:运行是否OK,请参阅对象所属的类中是否有调用的方法。

简单总结就是:成员函数在多态调用时,编译看等号左边,运行看等号右边。

2、在多态中,成员变量的特点:
无论编译和运行,都参考等号左边(引用型变量所属的类)。

3、在多态中,静态成员函数和特点:
无论编译和运行,都参考等号左边。

示例:
	class Fu
	{
		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
	{
		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  DuoTaiDemo
	{
		public static void main(String[] args) 
		{		
			Fu f = new Zi();
			System.out.println(f.num);//结果是5

			Zi z = new Zi();
			System.out.println(z.num);//结果是8

			f.method1(); //zi method_1 
			f.method2(); //fu method_2 
			//f.method3();//编译失败:因为父类中没有该方法
			f.method4();//fu method_4
			z.method4();//zi method_4
		}
	}

六、面向对象——多态的主板示例

需求:
电脑运行实例:电脑运行基于主板。

代码体现:
	class DuoTaiDemo
	{
		public static void main(String[] args) 
		{
			MainBoard mb = new MainBoard();
			mb.run();
			mb.usePCI(null);
			mb.usePCI(new NetCard());
			mb.usePCI(new SoundCard());
			
		}
	}
	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();
			}
		}
	}

	interface PCI //父类
	{
		public void open();
		public void 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");
		}
	}

七、面向对象——多态的扩展示例

需求:数据库的操作。
数据是:用户信息。

1,连接数据库。JDBC  Hibernate
2,操作数据库。
c create r read  u update  d delete
3,关闭数据库连接。

代码体现:
	class DBOperate
	{
		public static void main(String[] args) 
		{
			UserInfoDao ui = new UserInfoByHibernate();//多态的应用
			ui.add(user);
			ui.delete(user);
		}
	}

	interface UserInfoDao //接口型父类
	{
		public void add(User user);
		public void delete(User user);
	}

	class UserInfoByJDBC implements UserInofDao
	{ //子类实现接口
		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,关闭连接;
		}
	}

八、面向对象——Object类——equals() 

Object 类层次的根类,所有对象的直接或者间接父类。该类中定义的是所有对象都具备的功能。
Object 类中的 equals(Object obj)方法比较的是两个对象的内存地址值。
也就相当于 == 。
示例:
	class Demo
	{
	}
	class Object
	{
		public static void main(String[] args)
		{
			Demo d1 = new Demo();
			Demo d2 = new Demo();
			Demo d3 = d1;
			sop(d1.equals(d2));//false
			sop(d1.equals(d3));//true
			sop(d1==d2);//false
			sop(d1==d3);//true
		}
	}

但实际开发中比较两个对象的内存地址值是没有意义的,所以需要复写equals方法。
例如:
	class ObjectDemo 
	{
		public static void main(String[] args) 
		{
			Demo d1 = new Demo(4);
			Demo d2 = new Demo(5);
			System.out.println(d1.equals(d2));
			Person p1 = new Person();
			System.out.println(d1.equals(p1));
		}
	}
	class Demo //extends Object
	{
		private int num;
		Demo(int num)
		{
			//super();
			this.num = num;
		}
		public boolean equals(Object obj)
		{ //复写Object类中的equals方法
			if(!(obj instanceof Demo)) //判断
				return false;

			Demo d = (Demo)obj; //向下转型
			return this.num == d.num;
		}
	}
	class Person
	{
	}

九、面向对象——Object类——toString() 

toString()方法分解:
getClass().getName()+"@"+Integer.toHexString(hashCode())

代码分析:
	class ObjectDemo 
	{
		public static void main(String[] args) 
		{
			Demo d1 = new Demo();

			Class c = d1.getClass();

			System.out.println(d1.toString());  //Demo@15db9742
			
			System.out.println(d1.getClass().getName()); //Demo
			System.out.println(d1.hashCode()); //366712642 //十进制
			System.out.println(Integer.toHexString(d1.hashCode())); //15db9742 //十六进制
		}
	}
	class Demo
	{
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值