对成员变量的访问, 统一提供 setXXX,getXXX 方法.
下面请看一个 Student 实体对象类:
- public class Student implements Serializable {
- private Long id;
- private String name;
- private Integer sex;
- public Long getId() {
- return id;
- }
- public void setId(Long id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Integer getSex() {
- return sex;
- }
- public void setSex(Integer sex) {
- this.sex = sex;
- }
- }
分析: 对于上面的一个实体对象, 我想大家都已经很熟悉了. 将对象中的成员变量进行私有化, 外部程序是无法访问的. 但是我们对外提供了访问的方式, 就是 set 和 get 方法.
而对于这样一个实体对象, 外部程序只有赋值和获取值的权限, 是无法对内部进行修改, 因此我们还可以在内部进行一些逻辑上的判断等, 来完成我们业务上的需要.
到这里应该就明白封装对于我们的程序是多么重要. 下面再来说说继承的那点事.
三, 继承
3.1, 什么是继承
继承就是子类继承父类的特征和行为, 使得子类对象 (实例) 具有父类的实例域和方法, 或子类从父类继承方法, 使得子类具有父类相同的行为. 当然, 如果在父类中拥有私有属性(private 修饰), 则子类是不能被继承的.
3.2, 继承的特点
1, 关于继承的注意事项:
只支持单继承, 即一个子类只允许有一个父类, 但是可以实现多级继承, 及子类拥有唯一的父类, 而父类还可以再继承.
子类可以拥有父类的属性和方法.
子类可以拥有自己的属性和方法.
子类可以重写覆盖父类的方法.
2, 继承的特点:
提高代码复用性.
父类的属性方法可以用于子类.
可以轻松的定义子类.
使设计应用程序变得简单.
3.3, 继承的使用
1, 在父子类关系继承中, 如果成员变量重名, 则创建子类对象时, 访问有两种方式.
a, 直接通过子类对象访问成员变量
等号左边是谁, 就优先使用谁, 如果没有就向上找.
b, 间接通过成员方法访问成员变量
该方法属于谁, 谁就优先使用, 如果没有就向上找.
- public class FU {
- int numFU = 10;
- int num = 100;
- public void method(){
- System.out.println("父类成员变量:"+numFU);
- }
- public void methodFU(){
- System.out.println("父类成员方法!");
- }
- }
- public class Zi extends FU{
- int numZi = 20;
- int num = 200;
- public void method(){
- System.out.println("子类成员变量:"+numFU);
- }
- public void methodZi(){
- System.out.println("子类方法!");
- }
- }
- public class ExtendDemo {
- public static void main(String[] args) {
- FU fu = new FU();
- // 父类的实体对象只能调用父类的成员变量
- System.out.println("父类:" + fu.numFU); // 结果: 10
- Zi zi = new Zi();
- System.out.println("调用父类:" + zi.numFU); // 结果: 10
- System.out.println("子类:" + zi.numZi); // 结果: 20
- /** 输出结果为 200, 证明在重名情况下, 如果子类中存在则优先使用,
- * 如果不存在则去父类查找, 但如果父类也没有那么编译期就会报错.
- */
- System.out.println(zi.num); // 结果: 200
- /**
- * 通过成员方法调用成员变量
- */
- zi.method(); // 结果: 10
- }
- }
2, 同理:
成员方法也是一样的, 创建的对象是谁, 就优先使用谁, 如果没有则直接向上找.
注意事项:
无论是成员变量还是成员方法, 如果没有都是向上父类中查找, 绝对不会向下查找子类的.
3, 在继承关系中, 关于成员变量的使用:
局部成员变量: 直接使用
本类成员变量: this. 成员变量
父类成员变量: super. 父类成员变量
- int numZi = 10;
- public void method() {
- int numMethod = 20;
- System.out.println(numMethod); // 访问局部变量
- System.out.println(this.numZi); // 访问本类成员变量
- System.out.println(super.numFu); // 访问本类成员变量
- }
3.4, 重写, 重载
重写(override)
是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变. 即外壳不变, 核心重写!
- class Animal{
- public void move(){
- System.out.println("动物行走!");
- }
- }
- class Dog extends Animal{
- public void move(){
- System.out.println("狗可以跑和走");
- }
- }
- public class TestDog{
- public static void main(String args[]){
- Animal a = new Animal(); // Animal 对象
- Animal b = new Dog(); // Dog 对象
- a.move();// 执行 Animal 类的方法
- b.move();// 执行 Dog 类的方法
- }
- }
重写的规则:
1, 参数列表必须与被重写方法相同.
2, 访问权限不能比父类中被重写的方法的访问权限更低(public>protected>(default)>private).
3, 父类成员的方法只能被它的子类重写.
4, 被 final 修饰的方法不能被重写.
5, 构造方法不能
重载(overload)
是在一个类里面, 方法名字相同, 而参数不同. 返回类型可以相同也可以不同. 每个重载的方法 (或者构造函数) 都必须有一个独一无二的参数类型列表.
最常用的地方就是构造器的重载.
- public class Overloading {
- public int test(){
- System.out.println("test1");
- return 1;
- }
- public void test(int a){
- System.out.println("test2");
- }
- // 以下两个参数类型顺序不同
- public String test(int a,String s){
- System.out.println("test3");
- return "returntest3";
- }
- public String test(String s,int a){
- System.out.println("test4");
- return "returntest4";
- }
- public static void main(String[] args){
- Overloading o = new Overloading();
- System.out.println(o.test());
- o.test(1);
- System.out.println(o.test(1,"test3"));
- System.out.println(o.test("test4",1));
- }
- }
重载规则:
1, 被重载的方法必须改变参数列表(参数个数或者类型不一样).
2, 被重载的方法可以改变返回类型.
3, 被重载的方法可以改变访问修饰符.
3.5,this,super 关键字
super()关键字的用法
1, 子类的成员方法中, 访问父类的成员变量.
2, 子类的成员方法中, 访问父类的成员方法.
3, 子类的构造方法中, 访问父类的构造方法.
**this 关键字用法:**
1, 本类成员方法中, 访问本类的成员变量.
2, 本类成员方法中, 访问本类的另一个成员方法.
3, 本类的构造方法中, 访问本类的另一个构造方法.
== 注意:==
this 关键字同 super 一样, 必须在构造方法的第一个语句, 且是唯一的.
this 与 super 不能同时存在.
3.6, 构造器
继承关系中, 父子类构造方法的访问特点:
1, 在子类构造方法中有一个默认隐含的 super(); 调用, 因此一定是先调用父类构造方法, 再调用子类构造方法.
2, 子类构造可以通过 super(); 调用父类的重载构造.(重载)
3,super(); 的父类调用构造方法, 必须在子类构造中的第一行, 就是第一个; 号结束的元素, 并且只能调用一次.
3.7, 关于继承的注意事项:
1,Java 语言是单继承的, 一个子类只能有唯一一个父类
2,Java 语言可以是多级继承, 一个子类有一个父类, 一个父类还可以有一个父类.
3, 一个子类只有一个父类, 但是一个父类可以有多个子类.
四, 多态
4.1, 什么是多态
多态是同一个行为具有多个不同表现形式或形态的能力.
4.2, 多态的特点
1, 消除类型之间的耦合关系, 实现低耦合.
2, 灵活性.
3, 可扩充性.
4, 可替换性.
4.3, 多态的体现形式
继承
父类引用指向子类
重写
注意: 在多态中, 编译看左边, 运行看右边
- public class MultiDemo {
- public static void main(String[] args) {
- // 多态的引用, 就是向上转型
- Animals dog = new Dog();
- dog.eat();
- Animals cat = new Cat();
- cat.eat();
- // 如果要调用父类中没有的方法, 则要向下转型
- Dog dogDown = (Dog)dog;
- dogDown.watchDoor();
- }
- }
- class Animals {
- public void eat(){
- System.out.println("动物吃饭!");
- }
- }
- class Dog extends Animals{
- public void eat(){
- System.out.println("狗在吃骨头!");
- }
- public void watchDoor(){
- System.out.println("狗看门!");
- }
- }
- class Cat extends Animals{
- public void eat(){
- System.out.println("猫在吃鱼!");
- }
- }
4.4, 向上转型
**1, 格式: 父类名称 对象名 = new 子类名称();**
** 含义:** 右侧创建一个子类对象, 把它当作父类来使用
** 注意:** 向上转型一定是安全的
** 缺点:** 一旦向上转型, 子类中原本特有的方法就不能再被调用了.
来源: https://www.cnblogs.com/fenjyang/p/11462278.html