Java基础--继承和多态

来源:互联网 发布:kali 远程控制windows 编辑:程序博客网 时间:2024/05/30 13:41

Java的面向对象对象思想有三大特性:封装、继承、多态

第一节   继承

1. 继承的概念

继承是类与类之间的关系。在继承中,被继承的类叫做父类或者超类,继承的类叫做子类。子类继承父类后,子类中拥有父类中的成员,包括变量和方法,子类可以直接使用这些成员。在子类中可以添加自己的成员,也可以对父类成员进行覆盖(或重写)。

2. 继承的特点

a) 提高了代码的复用性

b) 让类于类之间产生了关系,有了这个关系,才有了多态的特性

c) 必须是类与类之间有所属关系才可以继承,所属关系 is a 

d) Java中只支持单继承 

因为多继承容易带来安全隐患:当多个父类中定义了相同功能,当功能内容不同时,子类不确定该调用哪一个,但是java保留了这种机制,并用另一种体现形式来完成表示:多实现。

3. 继承体系的使用

想要使用继承体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性的功能,一般类越往上共性越高,通过了解共性功能,就可以知道该体系的基本功能。那么这个体系已经可以基本使用了。

附上代码:  定义了一个Animal父类,再定义一个Cat子类继承Animal父类

class Animal{String name="动物类";void show(){System.out.println("父类调用");}}class Cat extends Animal{String name="猫类";void show(){System.out.println("子类调用");System.out.println(this.name);System.out.println(super.name);//super 对父类(超类)的用}}


4. 创建子类对象的流程

创建对象就是调用类的构造函数,当在类中没有定义构造函数时,系统会给出默认的构造函数。在继承的类中,创建子类对象不仅仅是调用了子类的构造函数,而是如下代码所示:

附上代码:

Cat c=new Cat();  //通过调用构造函数创建了一个新的Cat类对象


5. this 和 super在继承的使用

this 是表示对象本身的引用,super 是表示父类对象的引用。

用法:当成员变量和局部变量重名时,就必须使用this 关键字来区分成员变量和局部变量。当父类和子类具有相同名称的成员时,就必须使用super关键字来区分。

class Person{      String name;      void setName(String name)      {            this.name = name;      }}

this()关键字super()的区别,super()代表调用父类的构造函数,需要注意的是,如果不使用super()时,系统也会默认的给出super()来隐式调用父类的无参构造函数,当然也可以自己指定调用父类的哪一个构造函数。

问题:为什么子类一定要访问父类中的构造函数?

因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的,所以子类在对象初始化时,要先访问一下父类中的构造函数.

 如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来默认设置要访问父类中的构造函数

注意:super语句一定要定义在子类构造函数的第一行

总结:子类中所有的构造函数默认都会父类中空参数的构造函数,因为每一个构造函数内的第一行都有一句隐式super();当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。 子类中至少会有一个构造函数会访问父类中的构造函数。

附上代码:

class Tel{void show(){System.out.println("number");}}class NewTel extends Tel{void show()//覆盖父类方法{super.show();//访问父类中指定的构造函数System.out.println("and name");}}


6.继承中的访问控制

访问包括两种操作,调用和继承。关于继承中的访问控制,整理了课堂笔记图:

注意:在调用访问中,保护访问和默认访问控制符是没有区别的,但是在继承的访问中则是不同的:当子类和父类在同一个包下,保护访问和默认访问控制符是相同的,但是当子类和父类不在同一包中时,保护访问修饰符的成员时可以被继承的,而默认访问修饰符是不能被继承的。

private-》default--》protected--》public

 

第二节  多态

多态是指拥有名称相同,但根据不同情况拥有不同操作的性质,其中最常见的就是方法,当方法名相同时,在不同调用的情况下,它拥有不同的功能,方法的重载和重写都属于多态。

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

     1,多态的体现

父类的引用指向了自己的子类对象。

父类的引用也可以接收自己的子类对象。

      2,多态的前提

      必须是类与类之间有关系,要么继承,要么实现

      通常还有前提:存在覆盖。

      3,多态的好处

多态的出现大大的提高了程序的扩展性。

      4,多态的弊端

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

public class Demo {/** * 多态性 *  * @param args */public static void main(String[] args) {// A a1 = new A();// a1.i = 9; // a1属于父类对象,只能调用父类自己的对象// B b1 = new B();// b1.i = 1;// b1.j = 1;// b1属于子类对象,能调用父类也能调用自己新增的属性//// A a2 = new B();// a2.i = 3;// // a2.j=0; //a2是以父类的身份访问,所以不能调用子类// B b2 = (B) a2;// 向下转型,通过转为子类B// b2.i = 0;// b2.j = 0; // 能调用自己新增的属性//// B b3 = new B();// A a3 = b3;// 向上转型(直接转型)// a3.i = 0;// // a3.j=0;//向上转型后,隐藏了自身的新增特性// B b4 = (B) a1; // A是父类对象,在堆内存中开辟了一个空间,存放有i// b4.i = 0; // 转换为子类B后,以子类的身份去访问,// b4.j = 0; // 可是堆内存中并未开辟子类对象空间存放j,运行时报错// B b5 = new A(); //父类对象不能给子类引用赋值, 如:人 不一定是学生AA a = new AA();AA a1 = new BB();// instanceof来判断该引用类型变量所“指向”的对象是否属于该类或该类的子类System.out.println(a instanceof AA);System.out.println(a1 instanceof AA); // true //子类就是父类System.out.println(a1 instanceof BB); // true}}class AA { // 定义父类iint i;}class BB extends AA {// 继承于父类A的子类Bint j; // 子类新增属性}

A:父类:1,2,3

B:子类:重写2,3,新增4,5

A a = new B();

a:父类中的1,子类重写后的2,3(子类重写)

A a = new A();

B b = new B();

=的左边:什么类型的引用:就能调用相应类中的方法。

=的右边:什么类型的对象:子类对象就调用重写后的方法。

 

对象的多态性

对象:new 构造函数:堆。

栈:引用

instanceof:判断该引用是否属于某类,返回boolean类型。

对象的转型:

父类:A,子类:B

一个父类引用,可以指向父类对象,可以指向子类对象。

A a = new A();

A a = new B();  //父类引用指向子类对象

一个子类引用,指向子类对象,

B b = new B();

对象转型:

向上转型:子类类型--》父类类型

向下转型:父类类型--》子类类型:前提,向上转型

子类--》父类--》子类

A:父类,B,C,子类

B --》A--》B

C--》A--》C

B--》A---》C:错误。

引用是否属于某个类instanceof:引用  instanceof  类---》booleanA a = new A();a instanceof A-->truea instanceof B-->falsea instanceof C-->falseB b = new B();b instanceof A-->trueb instanceof B-->trueb instanceof C-->false


 

 

在多态中成员函数的特点:(重点掌握)

在编译时期:参阅引用类型变量所属的类中是否有调用的方法。

如果有,编译通过,如果没有则编译失败。

在运行时期:参阅对象所属的类中是否有调用的方法。

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

在多态中,成员变量的特点:

无论编译和运行,都参考左边(引用型变量所属类型)

 

在多态中,静态成员函数的特点:

无论编译和运行,都参考左边(引用型变量所属类型)