Java学习笔记5

封装、继承、多态是面向对象的三大特征,继承是实现类重用的重要手段,但是继承会带来一个最大的坏处,那就是破坏


封装。因此接下来介绍组合,组合是实现类重用的重要方式,能提供更好的封装性。


子类扩展父类的时候,可以从父类那里继承得到Field和方法,假设现在我们有足够的权限,那么子类就可以直接复用父


类的Field和方法,但继承在带来高度复用的同时,也带来了一个严重的问题,继承严重的破坏了父类的封装性。在封装


时,我们应该遵守这个原则:每个类都应该封装它内部信息和实现细节,而只暴露必要的方法给其他类使用。但通过继


承关系,子类可以直接访问父类的Field和方法,因此造成子类和父类的严重耦合。也就是说,父类的实现细节对子类不


再透明,子类可以访问父类的Field和方法,并且可以改变父类方法的实现细节,导致子类可以恶意更改父类的方法。


在保证父类有良好的封装性,不会被子类随意更改,我们在设计父类时通常遵循以下规则:


1、尽量隐藏父类的内部数据。尽量把父类的所有Field都设置成private访问类型,不要让子类直接访问父类的Field。


2、不要让子类随意访问、修改父类的方法。如果父类中存在的是一些为辅助其他的工具方法,应该使用private访问控制


符修饰,让子类无法访问该方法;如果父类中的方法需要被外部类调用,则用public修饰,但又不希望子类重写该方法


可以使用final修饰符;如果希望父类的某个方法被子类重写,但不希望被其他类自由访问,可以使用protected来修饰该


方法。


3、尽量不要在父类构造器中调用将要被子类重写的方法。


至于何时需要从父类派生新的子类?不单单需要保证子类是一个特殊的父类,而且需要具备以下两个条件之一:


1、子类需要额外增加属性,而不仅仅是属性值的改变。


2、子类需要增加自己独有的行为方式,包括增加新的方法或重写父类的方法。


面对继承带来的种种问题,如果只是出于类的复用的目的,并不一定需要使用继承。我们可以使用组合来实现。


如果需要复用一个类,除了把这个类当成基类来继承之外,还可以把该类当成另一个类的组合部分,从而允许新类直接


复用该类的public方法。使用组合可以把旧类对象作为新类的Field嵌入,用来实现新类的功能,因此,通常需要在新类里


使用private修饰被嵌入的旧类对象。比如以下代码:

class Computer{
	public void cpu(){
		System.out.println("计算机有CPU");
	}
}

class Cpu{
	private Computer computer;
	public Cpu(Computer computer){
		this.computer=computer;
	}
	public void cpu(){
		computer.cpu();
	}
}
public class ComputTest {
	public static void main(String[] args) {
		Cpu cpu=new Cpu(new Computer());
		cpu.cpu();
	}

}

总结以上内容,通常情况下,继承关系是从中多个子类里抽象出共有父类的过程,类似于组合关系中从多个整体类里提取嵌入类的过程;继承关系中从父类派生子类的过程,类

似于组合关系中把嵌入类对象组合成整体类的过程。总之,继承是一种“是(is-a)”的关系,组合表示的是“有(has-a)”的关系。

在Java中除了使用构造器类对单个对象进行初始化操作外,我们还可以通过初始化块来实现。在一个类中可以有多个初


始化块,相同类型的初始化块之间有顺序:前面定义的初始化块先执行,后面定义的初始化块后执行。使用static修饰的


初始化块,称为静态初始化块,在初始化块中可以定义局部变量、调用其他对象的方法,以及使用分支、循环语句等。


下面程序就定义了初始化块:

class Person{
	{
		int num=25;
		System.out.println("普通初始化块1");
	}
	static{
		int num=45;
		System.out.println("静态初始化块");
	}
	{
		int num=25;
		System.out.println("普通初始化块2");
	}
	public Person(){
		System.out.println("无参构造器");
	}
}

public class MainTest {

	public static void main(String[] args) {
		new Person();
	}

}

输出结果如下:

静态初始化块
普通初始化块1
普通初始化块2
无参构造器


从运行结果可以看出,当创建Java对象时,系统总是先调用静态初始化块,之后按顺序执行普通初始化块,最后才执行


构造器。静态初始化块是类相关的,用于对整个类进行初始化处理,静态初始化块也被称为类初始化块,也属于类的静


态成员,因此不能访问非静态成员。


最后值得指出的是:当JVM第一次主动使用某个类时,系统会在类准备阶段为该类的所有静态Field分配内存,在初始化


阶段负责初始化这些静态Field,初始化静态Field就是执行类初始化代码或者声明类Field时指定的初始值。关于类加载请


参看”Java类加载笔记(1)




转载请注明出处:http://blog.csdn.net/hai_qing_xu_kong/article/details/43876627     情绪控_ 



























  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值