资讯 小学 初中 高中 语言 会计职称 学历提升 法考 计算机考试 医护考试 建工考试 教育百科
栏目分类:
子分类:
返回
空麓网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
空麓网 > 计算机考试 > 软件开发 > 后端开发 > Java

Java-继承和多态

Java 更新时间: 发布时间: 计算机考试归档 最新发布

Java-继承和多态

1.继承:

1.1继承的概念

  • 概念
    一个类继承另一个类,则称继承的类为子类,被继承的类为父类。
  • 主要解决的问题
    共性的抽取,实现代码复用

1.共性:都具备的特性。例如猫,狗都属于动物类
2.java中不支持多层继承 建议不超过3层继承 而且只能继承一个类
3.父类=基类 子类=派生类

1.2继承的语法

java中表示类之间继承关系,用extend关键字来实现,具体如下;

	修饰符 class 子类 extends 父类{	//代码的实现    } 

例:

//父类->动物类class Animal{	String name;	int age;	public void eat(){		System.out.println(name + "正在吃饭");	}	public void sleep(){		System.out.println(name + "正在睡觉");	}}//子类->猫类 继承 动物类class Cat extends Animal{    //mew是Cat类独有的方法	void mew(){		System.out.println(name + "喵喵喵~~~");	}}//子类->狗类 继承 动物类class Dog extends Animal{	//bark是Dog类独有的方法	void bark(){		System.out.println(name + "汪汪汪~~~");	}}public class Test {	public static void main(String[] args) {		Dog dog = new Dog();		// Dog类中并没有定义任何成员变量,name和age属性肯定是从父类Animal中继承下来的		System.out.println(dog.name);		System.out.println(dog.age);		//Dog中没有eat()和sleep()方法,因为继承父类,所以可以调用父类的eat()和sleep()方法		dog.eat();		dog.sleep();		//bark是Dog类独有的方法		dog.bark();	}}

注:

1.子类继承父类,会把父类的成员变量和方法继承到子类。2.子类要有独有的方法,否则继承无意义。

1.3父类成员的调用

1.3.1子类调用父类的成员变量

1.子类与父类的成员变量不同名

public class Base {	int a;	int b;}public class Derived extends Base{	int c;	public void method(){		a = 10; // 访问从父类中继承下来的a 并修改		b = 20; // 访问从父类中继承下来的b 并修改		c = 30; // 访问子类自己的c 并修改	}}

2.子类与父类的成员变量同名

class Base {	int a;	int b;	int c;} class Derived extends Base{	int a; // 与父类中成员a同名,且类型相同	char b; // 与父类中成员b同名,但类型不同	public void method(){		a = 100; // 访问父类继承的a,还是子类自己新增的a?		b = 101; // 访问父类继承的b,还是子类自己新增的b?		c = 102; // 子类没有c,访问的肯定是从父类继承下来的c		// d = 103; // 编译失败,因为父类和子类都没有定义成员变量d	}}

在子类方法中 或者 通过子类对象访问成员时:

  1. 如果访问的成员变量子类中有,优先访问自己的成员变量。
  2. 如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
  3. 如果访问的成员变量与父类中成员变量同名,则优先访问自己的。
  4. 成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找。

1.3.2子类中访问父类的成员方法

1.成员方法名字不同

class Base {	public void methodA(){		System.out.println("Base中的methodA()");	}}class Derived extends Base{	public void methodB(){		System.out.println("Derived中的methodB()方法");}public void methodC(){	methodB(); // 访问子类自己的methodB()	methodA(); // 访问父类继承的methodA()	// methodD(); // 编译失败,在整个继承体系中没有发现方法methodD()}
总结:成员方法没有同名时,在子类方法中或者通过子类对象访问方法时,则优先访问自己的,     自己没有时再到父类中找,如果父类中也没有则报错。

1.成员方法名字相同

class Base {	public void methodA(){		System.out.println("Base中的methodA()");	}	public void methodB(){		System.out.println("Base中的methodB()");	}}class Derived extends Base{	public void methodA(int a) {		System.out.println("Derived中的method(int)方法");	}	public void methodB(){		System.out.println("Derived中的methodB()方法");	}	public void methodC(){		methodA(); // 没有传参,访问父类中的methodA()		methodA(20); // 传递int参数,访问子类中的methodA(int)		methodB(); // 直接访问,则永远访问到的都是子类中的methodB(),基类的无法访问到	}}

【说明】

派生类(子类):在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。

通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。
通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法适传递的参数选择合适的方法访问,如果没有则报错

1.4supe和this关键字

  • super作用
    在子类方法中访问父类的成员变量和方法
    super.变量名:访问父类的普通成员变量
    super.方法名();调用父类的的普通成员方法
    super():调用父类的构造方法
  • this作用
    this是当前对象的引用,当前对象即调用实例方法的对象

注:不能利用super调用父类的静态方法

this 会优先范围跟子类自己的,如果子类没有,访问的是父类的

class Base {	int a;	int b;	public void methodA(){		System.out.println("Base中的methodA()");	}	public void methodB(){		System.out.println("Base中的methodB()");	}}class Derived extends Base{	int a; // 与父类中成员变量同名且类型相同	char b; // 与父类中成员变量同名但类型不同	// 与父类中methodA()构成重载	public void methodA(int a) {		System.out.println("Derived中的method()方法");	} // 与父类中methodB()构成重写(即原型一致)	public void methodB(){		System.out.println("Derived中的methodB()方法");	}	public void methodC(){		// 对于同名的成员变量,直接访问时,访问的都是子类的->就近原则		a = 100; // 等价于: this.a = 100;		b = 101; // 等价于: this.b = 101;		// 注意:this是当前对象的引用		// 访问父类的成员变量时,需要借助super关键字		// super是获取到子类对象中从父类继承下来的部分		super.a = 200;//修改的父类成员变量数据		super.b = 201;//修改的父类成员变量数据		// 父类和子类中构成重载的方法,直接可以通过参数列表区分清访问父类还是子类方法		methodA(); // 没有传参,访问父类中的methodA()		methodA(20); // 传递int参数,访问子类中的methodA(int)		// 如果在子类中要访问重写的基类方法,则需要借助super关键字		methodB(); // 直接访问,则永远访问到的都是子类中的methodA(),父类类的无法访问到		super.methodB(); // 访问父类的methodB()	}}

注:

  1. 只能在非静态方法中使用
  2. 在子类方法中,访问父类的成员变量和方法。

1.5super和this的区别

  1. this是当前对象的引用,当前对象即调用实例方法的对象
  2. super相当于是子类对象中从父类继承下来部分成员的引用
  3. 在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
  4. 在构造方法中:this()用来访问本类构造方法,super()用于调用父类构造方法,两种调用不能同时在构造方法中出现
  5. 构造方法中一定会存在super()的调用,用户没有写编译器也会增加,但事实this()用户不写则没有
  6. super this不能同时出现,只能出现一次(在一个方法中) super this 必须写在方法的第一行
  7. 当子类构造完成之前,先帮助父类完成初始化

1.5.1代码块的执行顺序

		静态代码块>实例代码块>构造代码块

1:父类静态代码块优先于子类代码块执行,且最早执行
2:父类实例代码块和父类构造方法紧接着再执行
3:子类的实例代码块和子类的构造方法紧接着再执行
4:第二次实例化子类对象时,父类和子类的静态代码块都不会再执行

1.6子类构造方法

public class Base {	public Base(){		System.out.println("Base()");	}}public class Derived extends Base{	public Derived(){	// super(); // 注意子类构造方法中默认会调用基类的无参构造方法:super(),	// 用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,	// 并且只能出现一次		System.out.println("Derived()");	}}public class Test {	public static void main(String[] args) {		Derived d = new Derived();	}}结果打印:Base()Derived()

释:
在子类构造方法中,并没有写任何关于基类构造的代码,但是在构造子类对象时,先执行基类的构造方法,然后执行子类的构造方法,因为:子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。父子父子肯定是先有父再有子,所以在构造子类对象时,先要调用基类的构造方法,将从基类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整 。
注:

  • 在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法。
  • 在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。
  • super(…)只能在子类构造方法中出现一次,并且不能和this同时出现

1.7访问修饰符

2.多态

2.1多态的概念

  • 概念
  • 多态的概念:指多种形态,就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。

例如:狗和猫都去吃饭,狗吃狗粮,猫吃猫粮。

2.2多态的实现条件

1. 必须在继承体系下
2. 子类必须要对父类中方法进行重写
3. 通过父类的引用调用重写的方法

例:

class Animal {	String name;	int age;	public Animal(String name, int age){	this.name = name;	this.age = age;	}	public void eat(){		System.out.println(name + "吃饭");		}	}	class Cat extends Animal{		public Cat(String name, int age){			super(name, age);		} 	public void eat(){		System.out.println(name+"吃小鱼干");		}	}	public class Dog extends Animal {		public Dog(String name, int age){			super(name, age);		} 	public void eat(){		System.out.println(name+"吃狼骨头");	}} public class Test {// 编译器在编译代码时,并不知道要调用Dog 还是 Cat 中eat的方法// 等程序运行起来后,形参a引用的具体对象确定后,才知道调用那个方法// 注意:此处的形参类型必须时父类类型才可以	public static void eat(Animal a){		a.eat();	}	public static void main(String[] args) {		Cat cat = new Cat("元宝",2);//传入参数		Dog dog = new Dog("小七", 1);//传入参数		eat(cat);		eat(dog);	}} 运行结果:元宝吃小鱼干元宝正在睡觉小七吃狼骨头小七正在睡觉

2.3重写(发生再继承)

2.3.1重写的概念

  • 概念
    重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程
    进行重新编写, 返回值和形参都不能改变。即**外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

2.3.2重写的规则

  • 子类在重写父类的方法时,一般必须与父类方法原型一致: 返回值类型 方法名 (参数列表) 要完全一致
  • 被重写的方法返回值类型可以不同,但是必须是具有父子关系的。即继承关系
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected
  • 父类被static、private修饰的方法、构造方法都不能被重写。
    -重写的方法,可以使用@Override 注解来显式指定,有了这个注解能帮我们进行一些合法性校验。 例如不小心将方法名字拼写错了 (比如写成 aet),那么此时编译器就会发现父类中没有 aet方法,就会编译报错,提示无法构成重写。

2.3.3重写和重载的区别

重写:
1:方法名称相同
2:返回值相同//具有父子关系的可以不相同
3:参数列表相同(数据类型、个数、顺序)

  • 子类的访问权限要>=父类的权限
  • private修饰的方法、final修饰的方法、static修饰的方法 不可以重写
  • 当在父类中调用子类重写方法的时候 此时会调用子类重写的方法

重载:
1:方法名称相同
2:参数列表不同数据类型、个数、顺序)
3:返回值没有要求

重写和重载的区别

区别点重写重载
参数列表不能修改必须修改
返回类型不能修改(除非父子关系)可以修改
访问修饰符可以降低限制可以修改

2.4向上、向下转型

2.4.1向上转型

  • 概念
    创建一个子类对象,将其当成父类对象来使用。
  • 语法格式
    父类类型 对象名= new 子类类型();
    例:Animal animal = new Cat();
class Animal {	String name;	int age;	public void eat(){	System.out.println(name + "吃饭");	}}class Cat extends Animal{	public void eat(){	System.out.println(name + "吃小鱼干");	}}class Dog extends Animal{	public void eat(){	System.out.println(name + "吃狗粮");	}}public class Test {	// 2. 方法传参:形参为父类型引用,可以接收任意子类的对象	public static void eatFood(Animal a){		a.eat();	} 	// 3. 作返回值:返回任意子类对象	public static Animal buyAnimal(String var){		if("狗".equals(var) ){			return new Dog("狗狗",1);		}else if("猫" .equals(var)){			return new Cat("猫猫", 1);		}else{			return null;		}	}	public static void main(String[] args) {		Animal cat = new Cat("元宝",2); // 1. 直接赋值:子类对象赋值给父类对象		Dog dog = new Dog("小七", 1);		eatFood(cat);		eatFood(dog);		Animal animal = buyAnimal("狗");		animal.eat();		animal = buyAnimal("猫");		animal.eat();	}}

优缺点:
向上转型的优点:让代码实现更简单灵活。
向上转型的缺陷:不能调用到子类特有的方法。

2.4.2向下转型

  • 概念
    为了重新获得因为向上转型而丢失的子类独有的特性
  • 格式
    父类类型 父类对象 = 子类实例;
    子类类型 子类对象 = (子类)父类对象;
    例 Animal a = new Dog();
    Dog b = (Dog) a;

释:
向下转型不安全,用的比较少,一般情况用instanceof关键字来提高向下转型的安全

2.4.3 instanceof

  • 功能
    判断一个对象是否是某个类(或接口)的实例
    例 对象 instanceof 类(接口)
	//如果成立返回 true   否则 flaseif(对象 instanceof 类(接口)){	//运行这里的代码}
转载请注明:文章转载自 http://www.konglu.com/
本文地址:http://www.konglu.com/it/1094568.html
免责声明:

我们致力于保护作者版权,注重分享,被刊用文章【Java-继承和多态】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理,本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2023 成都空麓科技有限公司

ICP备案号:蜀ICP备2023000828号-2