Java类的封装、继承和重写
开发工具与关键技术:工具:myeclipse 技术:private,public,getter,setter,extends ,Override
作者:吴东梅
撰写时间:2019-05-02
1、封装
封装是将描述某类事物的数据与处理这些数据的函数封装在一起,形成一个有机整体,称为类。类所具有的封装性可使程序模块具有良好的独立性与可维护性,这对大型程序的开发是特别重要的。封装的目的是增强安全性和简化编程。
实现Java封装的步骤:
1、 修改属性的可见性来限制对属性的访问(一般限制为private)
2、 对每个值属性提供对外的公共方法访问,也就是创建getter和setter方法(将实例变量的首字母大写,在前面添加get或者set,变成getter和 setter方法名)
3、 封装的形式如下:
封装属性:private 属性类型 属性名称;
封装方法:private 方法返回类型 方法名称(参数);
类的封装实例
通常要将类中的属性封装,用关键字“Private”声明为私有,从而保护起来。用下图的写法是错误的,因为在声明属性weigth前,我加了private(私有)修饰符,所以对外界是不可见的,换句话说,就是对象不能通过点操作( . )直接访问这些私有属性,否则就会报以下图的错误,如图所示:这里的字段field,就是Java里的数据属性。
那么应该怎么解决这个问题呢?在类的设计时,程序设计人员都设计或存或取这些私有属性的公共接口,这些接口的外在表现形式都是公有(public)方法,而在这些方法里,我们可以对存或取属性的操作实施合理的检查,以达到保护属性数据的目的。
如下图所示,类私有属性的Setter和Getter方法:取值用getter。赋值用setter。
上图添加setWeigth和getWeigth方法,这些方法都是公有类型的,外界可以通过这些公有的接口来设置和取得类中的私有属性weigth。
方法的封装使用
既然可以用private将属性封装起来,当然也可以用private把方法封装起来,如下图所示,在上面封装属性的方法上用private多封装一个方法,然后在上面也是用点操作调用此封装方法,就会报以下图上的错误,因为私有方法是不对外开放的,所以就会报在类MyCat中的方法MakeSound()不可见。
这时,我们不应该用点操作调用此方法,因为一旦方法的访问权限被声明为私有的,那么这个方法就只能被类内部方法所调用。所以我们要在getWeigth()方法中添加MakeSound()方法的语句,因为访问权限控制符是对类外而言的,而在同一类中,所有的类成员属性及方法都是相互可见的,也就是说,它们之间是可以相互访问的。如下图所示即可成功调用此封装方法:
如果类中的某些数据在初始化后,不想再被外界修改,则可以使用构造方法配合私有化的setter函数来实现该数据的封装。这是因为,构造方法只能在实例化对象时自动调用一次,而方法的访问权限为私有类型,外界又不能调用,所以就达到了封装的目的。但是要注意这种方法在有些情况下即使这样做,私有属性也有可能被外界修改。如下图所示:
2、继承
继承的目的在于实现代码重写,对已有的成熟的功能,子类从父类执行“拿来主义”。继承能以既有的类为基础,进而派生出新的类。通过这种方法,便能快速地开发出新的类,而不需编写相同的程序代码。在Java中,通过继承可以简化类的定义,扩展类的功能。在Java中支持类的单继承和多层继承,但是不支持多继承,即一个类只能继承一个类而不能继承多个类。
实现的继承格式如下:
class 子类名 extends 父类
extends 是Java中的关键词。Java继承只能直接继承父类中的公有属性和公有方法,而隐含地(不可见地)继承了私有属性。如果不写继承的时候,默认继承Object。
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己类的引用。
如下图所示,是继承的方法:构造方法用于数据成员的初始化,但要“各司其职”,对来自父类的数据成员,需要调用父类的构造方法,使用super关键字加上对应的参数,就是调用父类的构造方法。
如下图所示,是调用上面写了继承的类,来执行后的结果。只实例化了一个Student类,却有三个参数,是因为虽然在Student类只声明了school属性,但是Student类直接继承Person类,因此也继承了Person类的所有属性。
继承可以提供方便,但是对于继承也有着许多限制,下面粗略了解一下继承的限制:
限制1:Java之中不允许多重继承,但可以多层继承。
如果想要一个类C想要同时继承到类A和类B的功能,那么就可以先让类B继承类A,类C再继承类B,那么类C就可以都拥有类A和类B的功能了,但是类C不可以同时继承类A和类B。
限制2:从父类继承的私有成员,不能被子类直接使用。
也就是说子类无法直接操作父类的私有属性,必须通过设置setter和getter方法间接操作。
限制3:子类在进行对象实例化时,从父类继承而来的数据成员需要先调用父类的构造方法来初始化,然后再用子类的构造方法来初始化本地的数据成员。
限制4:被final修饰的方法不能被子类覆写实例,被final修饰的类不能再被继承。
Java的继承性确实在某些时候提高了程序的灵活性和代码的简洁度,但是有时我们定义了一个类但是不想让其被继承,即所有继承关系到此结束,如何实现这一目的呢?为此,Java提供了final关键字来实现这个功能。final 在Java之中称为终结器:(1)在基类的某个方法上加final,那么在子类中该方法被禁止二次“改造”(即禁止被覆写);(2)通过在类的前面添加final关键字,便可以阻止基类被继承。
如下图所示:final标记的方法不能被子类覆写的实例:会报以下截图上的错,因为在子类中尝试推翻终局final,改动由从父类中继承而来的talk()方法,于是Java虚拟机就“罢工”报错了。
如下图所示:用final继承的限制的实例,一但继承的父类是用final修饰的,就会报以下的错误不能被子类继承的错误。
3、 覆写
3.1、 属性的覆盖
所谓的属性覆盖(或称覆写),指的是子类定义了和父类之中名称相同的属性。如下图所示:
3.2、方法的覆写
当一个子类继承一个父类,如果子类中的方法与父类中的方法的名称、参数个数及类型且返回值类型等都完全一致时,修饰符范围要大于等于父类方法的修饰符范围,就称子类中的这个方法“覆写”了父类中的方法。
子类覆写父类的实现,如下图所示:
从输出结果可以看到,在子类Student1中覆写了父类Person1中的talk()方法,所以子类对象在调用talk()方法时,实际上调用的是子类中定义的方法。
那如何在此基础上去调用父类的方法呢?如下图所示,super调用父类的方法:
就在下图画红线的部分用supper关键字去调用一下父类的方法即可。