代码举例:
class Creature{ //生物类//声明属性、方法、构造器
}
class Animal extends Creature{ //动物类
}
class Dog extends Animal{ //狗类
}
class DogTest{
public static void main(String[] args){
Dog dog = new Dog();
dog.xxx
}
1、从结果的角度来看,体现为类的继承性
当我们创建子类对象后,子类对象就获取了其父类(所有父类,直接或间接)中声明的所有的属性和方法,在权限允许的情况下,可以直接调用,
2、过程的角度来看:
当我们通过子类的构造器创建对象时,子类的构造器一定会直接或间接的调用到其父类的构造器,而其父类的构造器同样会直接或间接的调用到其父类的父类的构造器,....,.直到调用了object类中的构造器为止。
正因为我们调用过子类所有的父类的构造器,所以我们就会将父类中声明的属性、方法加载到内存中,供子类的对象使用;
《一个事务的多种形态》
多态性,是面向对象中最重要的概念,在Java中的体现: 对象的多态性: 父类的引用指向子类的对象格式:(父类类型: 指子类继承的父类类型,或者实现的接口类型)
父类类型 变量名 = 子类对象;
1,如何理解多态性?
理解:理解为一个事物的多种形态。
生活举例:
>女朋友:我想养一个宠物。
>孩子:我想要一个玩具。
>老板,张秘书,安排一个技术科的同事,跟我一起下周出差。
2,Java中多态性的体现:
父类的引用指向子类的对象。 (或子类的对象赋给父类的引用)
比如:Person p2 = new Man();
3、多态性的应用:
/**多态性的应用:虚拟方法调用
* 在多态的场景下,调用方法时。
*编译时,认为方法是左边声明的父类的类型的方法(即被重写的方法)
*执行式,实际执行的是子类重写父类的方法。
*简称为:编译看左边,运行看右边。
*/
4、多态性的使用前提:1.要有类的继承关系 2.要有方法的重写
5.多态的适用性:适用于方法,不适用于属性。
6、多态性的好处或弊端
6.1、好处6.1
极大的减少了代码的冗余,不需要重载太多方法;
开发中:
使用父类做方法的形参,是多态使用最多的场合。即使增加了新的子类,方法也无需改变,提高了扩展性符合开闭原则。
[开闭原则OCP]
。对扩展开放,对修改关闭
通俗解释: 软件系统中的各种组件,如模块 (Modules) 、类(Classes) 以及功能 (Functions)等,应该在不修改现有代码的基础上,引入新功能
举例:
多态的弊端?
在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法。但是由于声明为父类的引用导致我们没有办法直接调用子类特有的属性和方法。
》问题: Person p2 =new Man();
》针对于创建的对象,在内存中是否加载了Man类中声明的特有的属性和方法? 加载了
*问题:能不能直接调用Man 中加载的特有的属性和方法呢? 不能
package Test5029;
public class Person {
String name;
int age;
int id = 1001;
//方法
public void eat(){
System.out.println("人吃饭");
}
public void walk(){
System.out.println("人走路");
}
}
package Test5029;
public class Woman extends Person {
boolean isBeauty;
public void eat(){
System.out.println("女生应该少吃,减肥");
}
public void walk(){
System.out.println("女人窈窕的走路");
}
public void goShopping(){
System.out.println("女人喜欢逛街");
}
}
package Test5029;
public class man extends Person {
boolean isSmoking;
int id = 1002;
public void eat(){
System.out.println("男人多吃肉,长肌肉");
}
public void walk(){
System.out.println("男人笔挺的走路");
}
public void earnMoney(){
System.out.println("男人挣钱养家");
}
}
package Test5029;
public class PersonTest {
public static void main(String[] args) {
//多态性之前的场景:
Person p1= new Person();
man m1= new man();
//多态性
Person p2= new man();
/**多态性的利用:虚拟方法调用
* 在多态的场景下,调用方法时。
* 编译时,认为方法是左边声明的父类的类型的方法(即被重写的方法)
* 执行式,实际执行的是子类重写父类的方法。
* 简称为:编译看左边,运行看右边。
*/
p2.eat();
p2.walk();
//测试属性是否满足多态性? 不满足
System.out.println(p2.id); //1001
}
}
package Test5029;
public class PersonTeset1 {
public static void main(String[] args) {
Person p1 = new man();//声明类型 实例对象名 = new 类()
//不能直接调用子类特有的结构
//p1.earnMoney();
//System.out.println(p1.isSmoking);
//向下转型:使用强转符。
man m1 = (man)p1;
m1.earnMoney();
System.out.println(m1.isSmoking);
System.out.println(p1==m1);//true,p1和m1指向堆空间中的同一个对象
/**
* 向下转型可能会出现:类型转换异常 (CLassCastException)
*
*/
Person p2 = new Woman();
//man m2 = (man)p2;
//m2.earnMoney();
/**
* 1.建议在向下转型之前,使用instanceof进行判断,避免出现类型转换异常
* 2.格式 变量对象 instanceof A(类):判断对象a是否是类A的实例。
* 3.如果a instance0f A 返回true,则:
* a instanceof superA 其中,A 是superA的子类。
*/
if(p2 instanceof man){
man m2 = (man)p2;
m2.earnMoney();
}
if(p2 instanceof Woman){
System.out.println("Woman");
}
}
}