类的三大特性-多态

(一)多态的概念

1.多态,是面向对象的程序设计语言最核心的特征。按字面的意思就是“多种状态”。是允许将子类类型的对象定义成父类类型的一种技术。多态是通过子类重写父类的方法来实现的。
例如:Parent object = new Child();
2.多态是通过子类重写父类的方法来实现的。
3.多态性使得能够利用同一类(基类)类型来引用不同类的对象,以及根据所引用对象的不同,以不同的方式执行相同的操作。
4.虽然子类被定义成父类类型,但是通过“父类对象.方法()”的方式,实际调用的还是子类的代码。这也说明了“父类类型”只是一个“傀儡”,真正发号施令还是子类。
5.如果子类,没有重写父类的方法,默认调用父类中的方法。
前提:有继承关系,且有方法的重写。
多态的作用:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。
补充:

  • 多态后的对象不能调用父类中私有的方法。
  • 多态后的对象会屏蔽掉子类独有的属性。
  • 多态后的对象会屏蔽子类独有的方法。

(二)多态的例子

这里书写两种例子,简便的和一种便于深入理解的。

(1)第一种

//子类
public class Dog extends Animal {
	// 构造方法
	public Dog() {
	}
}
//父类
public class Animal {
	public int age;
	public Animal() {
	}
	public  void run(){
	}
}
public class DogTest {
	public static void main(String[] args) {
		 Animal dog=new Dog();//声明Animal类对象,可调用Animal的方法
         Dog.run();
	}
}

(2)第二种

class Super {
    public void test() {
        System.out.println("super is calling!");
    }
}
class Sub1 extends Super {
    public void test() {
        System.out.println("sub1 is calling!");
    }
}
class Sub2 extends Super {
    public void test() {
        System.out.println("sub2 is calling!");
    }
}
class Sub3 extends Super {
    public void test() {
        System.out.println("sub3 is calling!");
    }
}
public class SamplePolymorphism {
    public static void main(String[] args) {
        test1(); // 未使用多態
        System.out.println("------華麗的-----------------------分割線-----");
        test2(); // 使用多態
        System.out.println("------華麗的-----------------------分割線-----");
    }
    private static void test1() {
        Super s = new Super();
        Sub1 s1 = new Sub1();
        Sub2 s2 = new Sub2();
        Sub3 s3 = new Sub3();
        s.test();
        s1.test();
        s2.test();
        s3.test();
    }
    private static void test2() {
        Super s = new Super();
        Super s1 = new Sub1();
        Super s2 = new Sub2();
        Super s3 = new Sub3();
        s.test();
        s1.test();
        s2.test();
        s3.test();
    }
    private static void test3() {
        for (int i = 0; i < 9; i++) {
            Super s = rand();
            s.test();
        }
    }
}
运行结果:
super is calling!
sub1 is calling!
sub2 is calling!
sub3 is calling!
------華麗的-----------------------分割線-----
super is calling!
sub1 is calling!
sub2 is calling!
sub3 is calling!

test()方法设置为static,运行结果有什么不同?

super is calling!
sub1 is calling!
sub2 is calling!
sub3 is calling!
------華麗的-----------------------分割線-----
super is calling!
super is calling!
super is calling!
super is calling!

出现这种结果有多态中方法的静态和非静态的原因导致下文有说明。

public class Animal {
	public static String name;
//	public  String name;
	public int age;
}
public class Dog{
	public static String name;
	public int age ;
	}
public class DogTest {
	public static void main(String[] args) {
		 Animal.name="hello";
		 Dog.name="world";
		 Animal ani = new Dog();
		 ani.name="tom";
		 System.out.println(ani.name);
		 System.out.println(Animal.name);
		 System.out.println(Dog.name);
	}
}

}
输出结果:
tom
tom
null
此时ani为Animal类型绑定。
屏蔽Dog中的	public static String name;结果:
tom
tom
tom
如果子类父类中都用非静态声明,此时需要new新对象来调用,此时三个变量皆为独立的。
输出结果:
tom 		 Animal ani = new Dog();	
jerry        Animal ani1 = new Animal();
null         Dog ani2 = new Dog();

(三)多态确定对象的类型

(1)通过instanceof运算符来确定对象是否属于这个类型

    /*
	 * instanceof:判断对象是否是某个类(包括继承的父类)的实例
	 * 缺点:不能准确的判断该对象是Dog的实例,如果该对象是类的子类对象也会返回true
	 */
public static void main(String[] args) {
        Animal ani1= new Dog();
		Animal ani2 = new Cat();
		Animal ani3 = new Husky();
		System.out.println(isDog(ani1));
}
//判断ani1是否是Dog类型
public static boolean isDog(Animal ani) {
		if (ani instanceof Dog) {
			 return true;
		}
		return false;
	}

(2)通过getClass().getName()取得该类真正的类名

//通过对象.getClass().getName()获取对象的实例类名
	public static boolean isDog1(Animal ani) {
//		对象.getClass():返回该对象对应的Class对象
//		对象.getClass().getName():该对象对应的class对象的全类名
//		String str = ani.getClass().getName();
//		System.out.println(str);
		if(ani.getClass().getName().equals(Dog.class.getName())) {
			return true;
		}else {
			return false;
		}
	}

(四)静态和非静态的区别

1.多态是通过子类重写父类的方法来实现的。但是如果该方法是静态的,多态就不起作用。(或者是final的也不行)。对于父类子类中具有相同名字的静态变量,也会遵从这个结果,就是此时子类静态成员变量并不能覆盖掉父类静态成员变量,因为此时成员变量被绑定。
2.通过new关键字创建的对象数据存放在堆内存中,创建之后才能通过“对象名.方法名()”的方式使用。
3.Java的内存中,除了栈和堆以外,还有一个称为方法区(或称为持久代)的区域,用来存放静态数据。一个类只会存在一份数据,而且不需要创建对象就可以使用,可以直接使用“类名.方法名()”或“类名.变量名”的方式调用。
在这里插入图片描述

(五)静态变量和静态方法

1.静态变量:

  • 既可以直接使用“类名.静态变量名”的方式使用,也可以使用“对象名.静态变量名”的方式使用。
  • 因为一个类的静态数据在方法区中只有一份,因此同一种类型的对象共用同一份数据。即“对象名1.静态变量名”和“对象名2.静态变量名”和“类名.静态变量名”得到的数据是相同的。

2.静态方法:

  • 在静态方法里只能直接调用同类中其它的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。
  • 静态方法也不能使用this和super关键字。因为在this和super是在实例化之后。

(六)方法绑定

1.Java允许在类中声明两种方法:类(静态)方法和实例方法。类方法称为静态方法,实例方法称为非静态方法。
2.将方法的调用绑定到类称为“静态方法绑定”,绑定到对象是称为“动态方法绑定”。
3.多态就是应用了“动态方法绑定”,因此只有非静态方法才能使用多态。故如果该方法是静态的,多态就不起作用。(或者是final的也不行) 。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值