黑马程序员-继承 子类的实例化和final关键字*

------- android培训java培训、期待与您交流! ----------

当多个类中存在相同的属性和行为时,将这些内容抽取到单独一个类中,那么多个类不需要再定义这些属性和行为,只需要

继承单独的那个类即可。多个类称为子类,单独这个类称为父类或超类。
子类可以直接访问父类中的非私有的属性和行为。
通过extends关键字让类与类之间产生继承关系。
继承的出现提高代码的复用性,并提供了多态的前提。


java中只支持单继承,不支持多继承,因为多继承容易带来安全隐患:
当功能内容不同时,子类对象不确定要运行哪一个。但java保存了这种机制,通过多实现来完成。
但支持多层继承体系。
想要使用体系,先查阅体系父类的描述,因为父类中的定义的是该体系的共性内容。
定义继承时,不能为了获取某个类中的属性或行为而定义继承,必须要确定两个类间有"is a "的关系,否则没有继承关系。


为什么在具体调用时,要创建子类对象呢?
1.因为有可能父类不能创建的对象
2.创建子类对象可以有共性和特有属性即方法。


当子类创建对象时,会先加载父类的字节码文件,然后再加载子类的字节码文件。
在堆内存中会同时存在父类和子类的相同属性,在方法区中同时存在父类和子类的方法。
super和this的使用方法基本相同,this代表本类对象的引用,super代表父类对象的引用。
当父类中定义非私有属性时,在建立子类对象时,子类中没有定义该属性,那么调用该属性时,可以同时用this或者super来调用
该属性,如this.name或者super.name, 可以理解为子类继承父类的该属性,或者this和super都指向了子类对象。


函数的另一个特性:覆盖
子类继承父类时,沿袭了父类的功能,子类虽然具备该功能,但功能的具体内容有所改变,可以定义和父类相同的功能方法,来
保留父类功能定义,并重写功能内容。实现子类的特有功能。称之为函数的覆盖。
注意: 子类覆盖父类,必须保证子类的访问权限大于或等于父类,且父类的权限不能为私有。静态只能覆盖静态。


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

class Fu
{
	int num = 4;
	Fu()
	{
		System.out.println("fu run"+num);
	}
	Fu(int num)
	{
		this.num = num;
		System.out.println("fu run..."+num);
	}
}
class Zi extends Fu
{
	//int num ;当子类中没有定义num变量时,子类初始化时会沿袭父类num的值
	int num;
	/*当子类中也定义了num变量时,子类构造函数初始化时,通过super()调用父类构造函数而父类构造函数中调用了num
	  时,父类构造函数中的num调用的是父类中的num值,子类构造函数中调用的num是子类中的num值。因为在构造函数初始化
	  前,对象已经进行特有属性的显示初始化了。
	*/
	Zi()
	{
		
		System.out.println("zi run"+num);
	}
	Zi(int num)
	{
		//super();默认调用父类空参数构造函数
		//this();如果有this()时,会先调用本类中的空参数构造函数,在调用本类空参数构造函数时,又会先调用父类的空参数构造函数。
		//super(num);如果自定义super语句指定父类的具体构造函数,就会调用对应父类的构造函数。
		this.num = num;
		System.out.println("zi fun..."+num);
	}
}
class ExtendsDemo 
{


	public static void main(String[] args) 
	{
		Zi z1 = new Zi();
		Zi z2 = new Zi(5);
	}
}

为什么子类一定要访问父类中的构造函数:
因为父类中的数据子类可以直接获取,子类在对象初始化前需要参考父类是如何对这些数据进行初始化的,所以要先访问父类的
构造函数。可以在子类构造函数中自定义super语句来指定访问父类的具体构造函数。
注意: super语句一定要定义在子类构造函数的第一行。


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



final:最终,作为一个修饰符。
1.final可以修饰类,也可以修饰方法,变量。
2.final修饰的类不能被继承。为了避免被子类复写。
3.final修饰的方法不能被复写。
4.final修饰的变量时一个常量只能复制一次,既可以修饰成员变量,也可以修饰局部变量。
当在描述事物时,一些数据的出现值是固定的,这时为了增强阅读性,给这些值起个名字,方便与阅读。
而这个值不需要改变,所以加上final修饰。作为常量,全部大写,单纯间用_连接。
5.内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
6. final只对引用的”值“(即内存地址 )有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会
导致编译期错误。至于它所指向的对象的变化,final是不负责的。

final StringBuffer sb1 = new StringBuffer("aaa");
final StringBuffer sb2 = new StringBuffer("bbb");
sb1=sb2;//编译不通过,无法为最终变量分配地址值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值