多态

多态

可以理解为事物存在的多种体现形态。

举例: 人:男人,女人;  动物:猫,狗等

Object p = new Person(); 实例p只能调用Object类的方法,而不能调用Person里的定义的方法

instanceof 运算符:用于判断是否可以强制转换

instanceof 前一个操作通常是一个引用变量,后一个操作通常是一个类,用于判断前面的对象是否是后一个类或者其子类的实例对象。

1. 多态的体现

  • 父类的引用指向了自己的子类对象
  • 父类的引用也可以接收自己的子类对象

2. 多态的前提

  • 必须是类与类之间有关系。要么继承,要么实现
  • 存在覆盖

3. 多态的好处:

  • 多态大大提高了程序的扩展性

4. 多态的弊端:

  • 提高了扩展性,但是只能使用父类的引用访问父类中的成员。

举例:

package 多态;


abstract class Animal{

    //动物都具备吃的方法,且吃的东西不一样,用抽象
    abstract void  eat();
}

class Cat extends Animal{

    @Override
    void eat() {
        System.out.println("吃鱼!");
    }

    // 特有的方法
    public void catchMouse(){
        System.out.println("抓老鼠");
    }
}

class Dog extends Animal{

    @Override
    void eat() {
        System.out.println("吃骨头");
    }

    // 特有的方法
    public void kaijia(){
        System.out.println("看家");
    }
}

public class DuoTaiDemo {
    public static void main(String[] args) {
//        Animal cat = new Cat();
//        cat.eat();
        // cat.catchMouse(); // 不能被调用

        fun(new Cat());
        fun(new Dog());

        /*
        *   吃鱼!
            吃骨头
        * */
    }

    // 多态:只能调用父类的方法
    public static void fun(Animal a){
        a.eat();
    }
}

向下转型

abstract class Animal{
 
    //动物都具备吃的方法,且吃的东西不一样,用抽象
    abstract void  eat();
}
 
class Cat extends Animal{
 
    void eat() {
        System.out.println("吃鱼!");
    }
 
    // 特有的方法
    public void catchMouse(){
        System.out.println("抓老鼠");
    }
}
 
class Dog extends Animal{
 
    void eat() {
        System.out.println("吃骨头");
    }
 
    // 特有的方法
    public void kaijia(){
        System.out.println("看家");
    }
}
 
public class DuoTaiDemo2 {
    public static void main(String[] args) {
 
        fun(new Cat());
        fun(new Dog());
 
        /*
       	吃鱼!
		抓老鼠
		吃骨头
		看家
        * */
    }
 
    // 多态:始终都是子类对象在发生变化
    public static void fun(Animal a){  // Animal a = new Cat(); // 向上转型
    	//调用子类的方法
    	if(a instanceof Cat){
    		Cat cat = (Cat)a; // 向下转型
    		cat.eat();
    		cat.catchMouse();
    	}else if( a instanceof Dog){
    		
    		Dog dog = (Dog)a; 
    		dog.eat();
    		dog.kaijia();
    	}
    }
}

多态示例:

/*
 基础班学生:
 	睡觉,学习
 高级班学生:
 	睡觉,学习
 
 可将这两类事物进行抽象
 * 
 * */


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

//将学生要做的事封装成一个类
class DoStudent{
	public static void doSome(Student s){
		s.study();
		s.sleep();
	}
}

class BaseStudent extends Student{

	public void study() {
		System.out.println("我们学习java基础");
	}
	
	// 重写父类方法
	public void sleep(){
		System.out.println("做着睡");
	}
}

class AdvStudent extends Student{

	public void study() {
		System.out.println("我们学习java进阶");
	}
	// 重写父类方法
	public void sleep(){
		System.out.println("没法睡");
	}
	
}



// 如果要添加其他学生只需继承父类即可
public class DuoTaiDemo3 {
	public static void main(String[] args) {
		DoStudent.doSome(new BaseStudent());
		DoStudent.doSome(new AdvStudent());
	}
}

多态中成员的特点: 

package test;

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 = 10;

	// 重写父类的方法
	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");
	}
}
public class DuoTaiDemo4 {

	public static void main(String[] args) {
		Fu f = new Zi();
		f.method1();  // zi method_1  
		f.method2();  // fu method_2
		
		System.out.println(f.num);  //5 父类的
		Zi z = new Zi();
		System.out.println(z.num);  // 10 子类的
		
		f.method4();  // fu method_4
		z.method4();  // zi method_4

	}
}

/*
 * 
结论:

在多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。


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


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


*/

多态的扩展性 之 主板示例(重点**) 

 

// PCI 接口
interface PCI{
	public abstract void open();
	public abstract void close();
}

// 主板使用接口
class MainBorad{
	public void run(){
		System.out.println("主板开始运行");
	}
	// PCI p 多态和接口 提高扩展性
	public void usePCI(PCI p){
		if(p!=null){
			p.open();
			p.close();
		}
	}
}

// 网卡实现接口
class NetCard implements PCI{
	public void open(){
		System.out.println("网卡启动。。。");
	}
	public void close(){
		System.out.println("网卡退出。。");
	}
}

public class DuoTaiDemo5 {

	public static void main(String[] args) {
		MainBorad borad = new MainBorad();
		borad.run();  // 主板启动
		borad.usePCI(new NetCard()); // 启动接口,插入网卡
	}
}

// 每当需要插入一个硬件,只需实现PCI接口即可

多态的扩展性 之 数据库的连接(重点**)

 

 

// 定义一个接口
interface UserInfoDao{
	public abstract void add();
	public abstract void delete();
}

class UserByJDBC implements UserInfoDao{

	public void add() {
		System.out.println("连接数据库");
		System.out.println("添加数据");
		System.out.println("关闭数据库连接");
		
	}

	public void delete() {
		System.out.println("连接数据库");
		System.out.println("删除数据");
		System.out.println("关闭数据库连接");
	}
}

class UserByMybaties implements UserInfoDao{

	public void add() {
		System.out.println("连接数据库");
		System.out.println("添加数据");
		System.out.println("关闭数据库连接");
		
	}

	public void delete() {
		System.out.println("连接数据库");
		System.out.println("删除数据");
		System.out.println("关闭数据库连接");
	}
}

public class DBOperator {

	public static void main(String[] args) {
		UserInfoDao uidao= new UserByJDBC();
		uidao.add();
		uidao.delete();
		
		UserInfoDao uidao1= new UserByMybaties();
		uidao1.add();
		uidao1.delete();
		
	}

}

Object 类

Object:是所有对象的直接后者间接父类,传说中的上帝。
该类中定义的肯定是所有对象都具备的功能。

Object类中已经提供了对对象是否相同的比较方法。

如果自定义类中也有比较相同的功能,没有必要重新定义。
只要沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值