黑马程序员:面向对象三大特征之一:继承的介绍

本文详细解析Java中继承的概念、好处、安全隐患及其解决方式,并通过实例展示如何正确使用继承体系,包括变量、函数、构造函数的继承,以及继承过程中需要注意的问题。此外,文章还介绍了Java中的聚集关系(hasa)和如何区分聚合与组合。

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

继承,面向对象的特征之一,Java语言中,只支持单继承,不支持多继承(后期其实有多继承功能,叫多实现,多继承容易带来安全隐患【当多个父类中定义了相同功能,但功能内容不同时,子类对象不确定运行哪一个】)

关键字:extends  class Student extends Person    Student类会继承Person类的变量和方法,加载Student类前会先加载Person类,即 先加载父类再加载子类
继承的好处:
1.提高代码复用性
2.让类与类之间产生关系,有了这个关系,才有了多态的特性


注:当类与类之间有所属关系(is a)才可以继承,切勿因为简化代码而继承。如果父类中的功能有子类不需要用的,那就不应该继承

多继承的安全隐患示例:
class A
{
	void show()
	{
		System.out.println("a");
	}
}

class B
{
	void show()
	{
		System.out.println("b");
	}
}

class C extends A,B
{
	C c = new C();
	c.show();//这时候程序就不知道调用A还是B中的show()了。
}

Java支持多层继承,也就是一个继承体系  如:C继承B,B继承A
如何使用一个继承体系中的功能?
想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系的共性功能
通过了解共性功能,就可以知道该体系的基本功能,即该体系可以基本使用了。


在具体调用时,要创建最子类的对象,原因是最子类的对象可以查阅父类功能,又可使用自身特有功能


子父类出现后,类成员的特点:
类中成员:
1.变量
2.函数
3.构造函数


1.子父类中的变量
如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this,子类要访问父类中的同名变量,用super
super的使用和this的使用几乎一致
this代表的是本类对象的引用
super代表的是父类对象的引用

class Fu
{
	int num = 4;
}
class Zi extends Fu
{
	int num = 5;
	void show()
	{
		System.out.println(super.num); //super.num代表访问父类num变量值,只写num其实是this.num
	}
}
class ExtendsDemo
{
	public static void main(String[] args)
	{
		Zi z = new Zi()
		System.out.println(z.num); //结果为5
		z.show(); //结果为4,因show方法使用了super
	}
}

2.子父类中的函数
当子类出现和父类一模一样的函数(一模一样表示返回值类型、方法名、参数列表都一样)时,子类对象调用该函数,会运行子类函数的内容,
如同父类的函数被覆盖一样。
这种情况是函数的另一个特性:重写(覆盖【其实父类的方法还在内存当中,只是没有运行而已】)。前面学过的一个函数特性:重载


重写的应用:
当子类继承父类,沿袭了父类的功能(若父类中的成员被private,子类就看不到父类中此成员)到子类中,但子类想输出功能中不同的内容,
这时,没必要定义新功能,而是使用重写其内容,保留父类的功能定义。

class Fu
{
	void show()
	{
		System.out.println("vb");
	}
}

class Zi extends Fu
{
	void show()
	{
		System.out.println("java");
	}
}

class ExtendsDemo
{
	public static void main(String[] args)
	{
		Zi z = new Zi();
		z.show(); //结果:java
	}
}

重写有利于功能(方法)的扩展:
class Tel
{
	void show()
	{
		System.out.println("number");
	}
}

class NewTel extends Tel
{
	void show()
	{
		//System.out.println("number"); //通过引用父类解决:super.show()
		super.show(); //这句话的意思是引用父类的show()方法
		System.out.println("name");
		Systme.out.println("picture");
	}
}

注:
1. 子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖(注意,若父类中被覆盖成员被private修饰,则无法覆盖,因为子类无权限看到父类中存在该成员),否则编译失败
2. 静态只能覆盖静态


重写与重载的区别:
重载:只看同名函数的参数列表
重写:子父类方法要一模一样



3.子父类中的构造函数
在对子类对象进行初始化时,父类的构造函数也会运行,
那是因为子类的构造函数默认 第一行有一条隐式的语句 spuer();
super():会访问父类中空参数的构造函数,而且 子类中所有的构造函数默认第一行都是super();
例:

class Fu
{
	Fu()
	{
		System.out.println("Fu run");
	}
}

class Zi extends Fu
{
	Zi()
	{
		//super();   这就是JVM自动加上的隐式语句
		System.out.println("Zi run");
	}
	Zi(int x)
	{
		//super(); 每一个构造函数都会自动加上这句隐式语句
		System.out.println("Zi"+x);
	}
}

class ExtendsDemo
{
	public static void main(String[] args)
	{
		Zi z = new Zi(); //这语句输出:Fu run Zi run
		Zi z = new Zi(4); //这语句输出:Fu run Zi4
	}
}

为什么子类一定要访问父类中的构造函数?
因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的,
所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果要访问父类中制定的构造函数,可以通过手动定义super语句的方式来指定。
注:
super语句一定要定义在子类构造函数的第一行。构造函数中this()与super()只能存在一个【原因:super和this语句都要写在第一行,为什么要写在第一行,因为初始化动作要先做】
当父类中没有空参数的构造函数时(定义了指定构造函数而没定义空参数的构造函数),子类必须手动形式通过super语句形式来指定要访问的构造函数。
子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数


聚集(has a):聚合、组合
从生活中举例说明聚合和组合的区别
聚合:球队中的一员,球队由N个成员组成
组合:人的手、心脏,人由N多器官和其他东西组成,组合的关系更为紧密。

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------详细请查看: http://edu.youkuaiyun.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值