浅谈对于封装、继承与多态的理解(Java)
目录
封装
继承
父类成员的访问
如何在子类中访问父类同名的成员
子类构造方法
代码块在继承上的执行顺序
多态
多态的实现条件
重写
多态的优缺点
面向对象程序的三大特征:封装继承和多态。
封装
· 封装:将数据和操作数据的方法进行有效的结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互
Java主要通过类和访问权限来实现封装,类可以将数据以及封装数据的方法结合在一起,而访问权限用来控制方法或者字段是否能在类外使用。
访问权限限定符有四个:public、protected、private、default(默认权限)
继承
面向对象思想中提出了继承的概念,专门用来提取代码的共用性,实现代码复用。继承允许程序员在保持原有类特性的基础上进行扩展,添加新的功能,这样产生新的类称为派生类。继承主要解决的问题就是共性的抽取,实现代码的复用。
继承的语法
修饰符 class 子类 extends 父类 {}
代码示例
父类Animal.java
public class Animal {public String name;public int age;public void eat() {System.out.println(this.name + "吃饭");}public void sleep() {System.out.println(this.name + "睡觉");}
}
子类Cat.java
public class Cat extends Animal {public void mew() {System.out.println(this.name + "~喵");}
}
子类会将父类的成员方法和变量继承到子类中,子类继承父类后需要添加自己特有的成员变量和方法。
父类成员的访问
· 当父类和子类不存在同名变量时,子类可以任意访问父类的成员变量。
public class Base {int a;int b;
}
class Derived extends Base {int c;public void method() {a = 10;//访问从父类继承下来的b = 20;//访问从父类继承下来的c = 30;//访问子类自己的cSystem.out.println("a = " + a + ", b = " + b + ", c = " + c);}
}
class Test {public static void main(String[] args) {Derived derived = new Derived();derived.method();}
}
· 子类和父类存在同名变量
public class Base {int a;int b;int c;
}
class Derived extends Base {int a;//与父类的成员变量名相同,且类型相同char b;//与父类中成员变量名相同,但类型不同public void method() {a = 10;//优先访问自己的b = 101;//优先访问自己的c = 30;//子类中未定义c,访问从父类继承下来的System.out.println("a = " + a + ", b = " + b + ", c = " + c);}
}
class Test {public static void main(String[] args) {Derived derived = new Derived();derived.method();}
}
在子类方法中或者通过子类对象访问成员时
· 如果访问的成员变量子类中有,优先访问子类的成员变量
· 如果访问的成员变量子类中没有,访问从父类继承的,如果父类也未定义,则编译报错
· 如果访问的成员变量与父类的成员变量名称相同,优先访问子类的,即子类将父类的同名变量隐藏了
· 在子类中访问父类的成员方法时
· 当成员方法不同名时,优先访问自己的,如果子类中没有,就去父类中找,如果父类中也没有就报错
· 当成员方法同名时:
通过子类对象访问父类和子类同名的方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法时传递的参数选择合适的方法访问,如果没有报错;如果父类和子类同名方法原型一致(重写),则只能访问到子类的,父类的无法通过子类对象直接访问到
如何在子类中访问父类同名的成员
使用super关键字,super关键字的作用就是在子类中访问父类中的与子类同名的成员
例如:
public class Base1 {int a = 10;public void method() {System.out.println("父类同名方法");}
}
class Derived1 extends Base1 {int a = 20;public void method() {System.out.println("子类同名方法");}public void superMethod() {System.out.println(super.a);super.method();}
}
class Test1 {public static void main(String[] args) {Derived1 d = new Derived1();d.superMethod();}
}
注意事项:super只能在非静态方法中使用;在子类方法中,访问父类的成员变量
子类构造方法
在构造子类对象时,先执行父类的构造方法,然后再执行子类的构造方法。因为子类对象是一个父类对象,在构造子类对象时,先要将父类继承下来的成员初始化完整,然后再初始化子类自己新添加的成员
注意事项
1、如果父类定义了无参或者默认的构造方法,在子类构造方法第一行会默认有隐含的super()调用,用来调用父类的构造方法
2、如果父类的构造方法带有参数,此时编译器不会再给子类生成默认的构造方法,就需要coder为子类显示的定义构造方法,并在子类构造方法中选择合适的父类构造方法调用
3、在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数的第一条语句
4、super(...)只能在子类构造方法中出现一次,且不能和this同时出现
public class Base2 {String name;int age;public Base2() {System.out.println("Base2()");}
}
class Derived2 extends Base2 {public Derived2() {System.out.println("Derived2()");}
}
class Test2 {public static void main(String[] args) {Derived2 derived2 = new Derived2();}
}
先执行父类的构造方法,再执行子类的
如果基类的构造方法带有参数,那么在子类中需要使用super(...)调用父类的构造方法
在子类使用了super后,可以额外定义自己的构造方法
代码块在继承上的执行顺序
通过下述代码来观察代码块在继承上的执行顺序
public class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;System.out.println("Person: 构造方法执行");}{System.out.println("Person: 普通代码块执行");}static {System.out.println("Person: 静态代码块执行");}
}
class Student extends Person {public Student(String name, int age) {super(name, age);System.out.println("Student: 构造方法执行");}{System.out.println("Student: 普通代码块执行");}static {System.out.println("Student: 静态代码块执行");}
}
class Test3 {public static void main(String[] args) {Student student = new Student("小明", 10);System.out.println("============================");Student student1 = new Student("小光", 15);}
}
通过观察,可以总结出
1、静态代码块无论子类还是父类都是优先初始化的,且父类先初始化再初始化子类,且只初始化一次
2、 普通代码块优先于构造方法执行,且父类的先执行,执行完后再执行子类的
多态
通俗的说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时产生不同的状态
多态的实现条件
在Java中要实现多态,必须要满足以下几个条件:
1、必须在继承的体系下
2、子类必须要对父类中的方法进行重写
3、通过父类的引用调用重写的方法
多态的体现,在代码运行时,当传递不同的对象时,会调用对应类中的方法
public class Animal2 {String name;int age;public Animal2(String name, int age) {this.name = name;this.age = age;}public void eat() {System.out.println(name + "吃饭");}
}
class Cat2 extends Animal2 {public Cat2(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println(name + "吃鱼");}
}
class Dog extends Animal2 {public Dog(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println(name + "吃骨头");}
}
class TestAnimal {public static void eat(Animal2 a) {a.eat();}public static void main(String[] args) {Cat2 cat = new Cat2("喵", 10);Dog dog = new Dog("茶杯犬", 5);eat(cat);eat(dog);}
}
在编写eat方法时,参数类型为Animal(父类),此时该方法内部并不知道也不关注当前的a指向的是哪个子类的实例,此时a这个引用调用eat方法可能会有多种不同形式的表现(和a引用的实例相关),这种行为就称为多态。
重写
也称为覆盖,重写是子类对父类非静态、非private、非final修饰、非构造方法等的实现过程进行重新编写,返回值和形参都不能变,也就是外壳不变,重写核心,重写的好处在于子类可以根据需要,定义特定于自己的行为。
方法重写的规则
1、子类在重写父类方法时,一般必须与父类方法原型一致:修饰符、返回值类型、方法名、参数列表要完全一致
2、JDK1.7以后,被重写的方法返回值类型可以不同,但是必须具有父子关系
3、访问权限不能比父类方法的访问权限低
4、父类中被static、private修饰的方法、构造方法都不能重写
5、子类和父类在同一个包中,则子类可以重写父类的所有方法,除了声明为private和final的方法
6、子类和父类不在同一个包中,那么子类只能够重写父类声明为public和protected的非final方法
多态的优缺点
1、能够降低代码的“圈复杂度”,避免使用大量的if-else语句
2、可扩展能力强,如果要新加一种状态,使用多态的方式代码改动成本较低
3、多态的缺点是运行效率较低
浅谈对于封装、继承与多态的理解(Java)相关推荐
- 浅谈c++中继承体系中易错点
浅谈c++中继承体系中易错点 目前,就我工作经验来看,在c++中继承体系中总爱搞错的有两点: 不把基类中需要覆盖的方法为设置为虚方法. 不把基类中的析构函数设置为虚方法. 就第一点而言,如果基类中需要 ...
- 浅谈架构、操作系统、芯片的理解
浅谈架构.操作系统.芯片的理解 序言 架构篇 操作系统篇 芯片篇 序言 从事物联网行业,总是会有一些概念上的疑惑,对此网上查阅了资料,结合自己理解,做了一些汇总,方便自己以后查阅. 架构篇 我们接触架 ...
- 未来生活里掌握计算机技术的重要性,浅谈计算机教育重要性的几点理解.doc
浅谈计算机教育重要性的几点理解.doc 浅谈计算机教育重要性的几点理解 摘 要:本文主要阐述了计算机教育重要性的认识与理解,计算机教育如何适应现在与未来,是摆在我们面前刻不容缓的研究课题,需要我们认真 ...
- 计算思维不是计算机科学的核心素养,浅谈 对 信息技术学科核心素养 的理解...
浅谈 对 信息技术学科核心素养 的理解 陆阳 贵州省 清镇市第一中学 551400 摘要:随着<中国学生发展核心素养>的发布,核心素养成为我国深化基础教育课程改革的新指向,作为连接总的核心 ...
- java 继承重写_java 封装 继承 重写 多态
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. 好处: 将变化隔离.便于使用.提高重用性.提高安全性 封装原则: 将不需要对外提供的内容都隐藏起来.把属性都隐藏,提供公共方法对其访问. ...
- 面试:对封装、继承、多态的理解。
1.封装 封装:就是隐藏对象的属性和实现细节,仅对外提供公共访问方式. 封装的好处:隐藏类的实现细节;让使用者只能通过程序员规定的方法来访问数据;可以方便的加入存取控制语句,限制不合理操作. ...
- 封装、继承、多态 通俗理解
比较抽象,只是一种概念,刚开始学的时候无需太过于深究,如果要你一上来学JAVA就理解这些东西,有点牵强,你所要做的就是至少看到代码知道这个用到的是什么. 封装的概念好比一辆汽车,你学开车的时候只需学会 ...
- 面向对象 详解笔记 方法 类 对象 封装 继承 重写 多态 接口
文章目录 面向过程&面向对象 面向过程 面向对象 什么是面向对象 回顾方法及加深 方法的定义 修饰符 返回类型 break:跳出switch,结束循环和return的区别 方法名:注意规范就o ...
- 本质论之封装继承和多态的介绍
关于 类,我有一些话想说 说到类那就说到了面向对象的灵魂了,没有它也就没有了封装.继承and多态这些东西了.我还记得在读研期间每次看到这些都望而却步,甚至我搞不懂对象和类的区别(这里防止有人也不知道区 ...
最新文章
- WCF学习之旅—WCF第二个示例(七)
- 引用和指针的区别?传引用比传指针安全,为什么?如果我使用常量指针难道不行吗?
- 双层lstm每层有自己的权重参数吗_一幅图真正理解LSTM的物理结构
- python 判断目录和文件是否存在,若不存在即创建
- Android 屏幕常亮、低电量监听
- Linux 中的驱动开发的初学者体会
- 在VMware Workstation中设置双网卡实现SSH使用固定IP登录并且在虚拟系统中任意访问Internet...
- Error:Can’t find import 2508 in coredll.dll问题解决
- [转]jQuery 读取 xml
- 气象ts评分_给大家分享一个格点插值到站点然后TS评分的程序
- 2021技术文大盘点 | 打包过去,​面向未来
- Jquery通过遍历数组给checkbox赋默认值
- 【BZOJ-2435】道路修建 (树形DP?)DFS
- MATLAB如何修改打开时的默认文件夹或默认路径
- Android Progress、SeekBar 实现进度条、可滑动的进度条
- Atitit.自然语言处理--摘要算法---圣经章节旧约39卷概览bible overview v2 qa1.docx
- SimpleFOC(八)—— 理论+实践 深度分析SVPWM
- AndroidStudio报错解决方案
- TGA文件格式分析和图片举例
- C++中#define宏定义的min与max函数