Java中的继承、封装、多态的理解
Java中的继承、封装、多态
继承的理解:
1、继承是面向对象的三大特征之一,也是实现代码复用的重要手段。Java的继承具有单继承的特点,每个子类只有一个直接父类。
2、Java的继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类称为父类(有的也称其为基类、超类),父类和子类的关系,是一种一般和特殊的关系。就像是水果和苹果的关系,苹果继承了水果,苹果是水果的子类,水果是苹果的父类,则苹果是一种特殊的水果。
3、Java使用extends作为继承的关键字,extends关键字在英文是扩展的意思,而不是继承。为什么国内把extends翻译成继承呢?除了与历史原因有关外,把extends翻译成为继承也是有其道理的:子类扩展父类,将可以获得父类的全部属性和方法,这与汉语中得继承(子辈从父辈那里获得一笔财富成为继承)具有很好的类似性。值得指出的是:Java的子类不能获得父类的构造器。
4、实例:
class BaseClass{
public double weight;
public void info() {
System.out.println("我的体重是"+weight+"千克");
}
}
public class ExtendsDemo001 extends BaseClass {
public static void main(String[] args) {
//创建ExtendsDemo001对象
ExtendsDemo001 ed = new ExtendsDemo001();
//ExtendsDemo001本身没有weight属性,但是ExtendsDemo001的父类有weight属性,也可以访问ExtendsDemo001对象的属性
ed.weight = 56;
//调用ExtendsDemo001对象的info()方法
ed.info();
}
}
打印结果为:我的体重是56.0千克
5、Java类只能有一个父类。这句话是错误的,应该这样说:Java类只能有一个直接父类,可以有无限多个间接父类,如:
class Fruit extends Plant{…….}
class Apple extends Fruit {…….}
重写父类的方法:
1、 大部分的时候,子类总是以父类为基础,额外添加新的属性和方法。但有一种情况例外:子类需要重写父类的方法。例如鸟类都包含了飞翔的方法,其中鸵鸟是一种特殊的鸟类,因此鸵鸟也是鸟的子类,因此它也将从鸟类获得飞翔方法,但这个飞翔方法明显不适合鸵鸟,为此,鸵鸟需要重写鸟类的方法。
2、 如下代码可以帮助理解重写:
1) class Bird{
2) //Bird类的fly()方法
3) private void fly(){
4) System.out.println("我要在天空中飞翔");
5) }
6) }
7) public class OcerrideTest extends Bird{
8) //重写Bird类的fly()方法
9) public void fly(){
10) System.out.println("我只能在地上奔跑");
11) }
12) public static void main(String[] args) {
13) //创建OcerrideTest对象
14) OcerrideTest ot = new OcerrideTest();
15) ot.fly();
16) }
17) }
打印结果为:我只能在地上奔跑
这种子类包含父类同名方法的现象被称为方法重写,也被称为方法覆盖(Override)。
方法的重写要遵循“两同两小一大”规则:
⑴ “两同”:方法名相同;形参列表相同。
⑵ “两小”:子类方法之返回类型应比父类方法返回值类型更小或相等;子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等。
⑶ 子类方法的访问权限应比父类方法更大或相等
尤其需要指出的是:覆盖方法和被覆盖方法要么都是类方法,要么都是实例方法,不能一个是类方法,一个是实例方法,例如下面的代码将会有编译错误:
Class BaseClass{
public static void test(){…….}
}
Class SubClass extends BaseClass{
public void test(){………….}
}
若想调用父类中的fly()方法,则只需在子类中fly()方法中加上如下代码即可:
super.fly();
注意:super和this一样,都不能出现在static的方法中
调用父类构造器
1、看如下程序定义的Basehe Sub类,其中Sub类是Base类的子类,程序在Sub类的构造器中使用super来调用Base构造器里的初始化代码。
class Base{
public double size;
public String name;
public Base(double size, String name){
this.size=size;
this.name=name;
}
}
public class Sub extends Base{
public String color;
public Sub(double size, String name, String color){
//在子类构造器中调用父类构造器,使用super调用来实现
super(size,name);
this.color = color;
}
public static void main(String[] args) {
Sub s = new Sub(5.6,"测试对象","红色");
System.out.println(s.size+"------"+s.name+"------"+s.color);
}
}
打印结果为:5.6------测试对象------红色
静态初始化块
1、如果定义初始化块时使用了static修饰符,则这个初始化块,就变成了静态初始化块,也被称作为类初始化块。静态初始化块是类相关的,系统将在类初始化阶段执行静态初始化块,而不是在创建对象时才执行。因此静态初始化块总是比普通初始化块先执行
封装的理解:
1、封装(Encapsulation)是面向对象的三大特征之一,它指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。
2、掌握了访问控制符的用法之后,下面通过使用合理的访问控制来定义一个Person类,这个Person类就实现了良好的封装。代码如下:
public class Person {
public static void main(String[] args) {
Person p = new Person();
p.setAge(10);
System.out.println(p.getAge());
}
//将属性使用private修饰,将这些属性隐藏起来
private String name;
private int age;
//提供方法来操作name属性
public void setName(String name) {
//对姓名执行合理的校验
if(name.length() > 6 || name.length() < 2){
System.out.println("您的姓名不符合要求");
}else{
this.name = name;
}
}
public String getName() {
return this.name;
}
//提供方法来操作age属性
public void setAge(int age) {
if(age>100 || age<0){
System.out.println("您的年龄必须要在0~100之间");
}else{
this.age = age;
}
}
public int getAge() {
return this.age;
}
}
运行结果为:10
多态的理解:
1、多态(Polymorphism)是面向对象的三大特征之一。
2、Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时的类型由声明该变量时使用的类型决定,运行时的类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就会出现所谓的多态(Polymorphism)
先看下面的程序:
class SuperClass{
public int book = 6;
public void base() {
System.out.println("父类的普通方法base()");
}
public void test(){
System.out.println("父类中北覆盖的方法");
}
}
public class PloymorphismTest001 extends SuperClass{
//重新定义一个book实例属性,覆盖父类的book实例属性
public String book = "Java疯狂讲义";
public void test() {
System.out.println("子类中覆盖父类的方法");
}
private void Dmeo() {
System.out.println("子类中普通的方法");
}
//主方法
public static void main(String[] args) {
//下面编译时类型和运行时类型完全一样,因此不存在多态
SuperClass sc = new SuperClass();
System.out.println("book1= "+sc.book);//打印结果为:6
//下面两次调用将执行SuperClass的方法
sc.base();
sc.test();
//下面编译时类型和运行时类型完全一样,因此不存在多态
PloymorphismTest001 pt = new PloymorphismTest001();
System.out.println("book2= "+pt.book);//打印结果为:Java疯狂讲义
//下面调用将执行从父类继承到的base方法
pt.base();
//下面调用将执行当前类的test方法
pt.test();
//下面编译时类型和运行时类型不一样,多态发生
SuperClass sscc = new PloymorphismTest001();
//结果表明访问的是父类属性
System.out.println("book3= "+sscc.book);//打印结果为:6
//下面调用将执行从父类继承到得base方法
sscc.base();
//下面调用将执行当前类的test方法
sscc.test();
//因为sscc的编译类型是SuperClass,SuperClass类没有提供Demo()方法
//所以下面代码编译时会出现错误
//sscc.Demo();
}
}
程序运行结果为:
book1= 6
父类的普通方法base()
父类中北覆盖的方法
book2= Java疯狂讲义
父类的普通方法base()
子类中覆盖父类的方法
book3= 6
父类的普通方法base()
子类中覆盖父类的方法
上面程序的main方法中显示创建而来3个引用变量,对于前两个引用变量sc和pt,它们编译时类型和运行时类型完全相同,因此调用它们的属性和方法非常正常,完全没有问题。但第三个引用变量sscc,则比较特殊,它编译时类型是SuperClass ,而运行时类型是PloymorphismTest001,当调用该引用变量的test方法时,实际上是执行PloymorphismTest001类中覆盖后的test方法,这就是多态。
当把一个子类对象直接赋给父类引用变量,例如上面的SuperClass sscc = new PloymorphismTest001();这个sscc引用变量的编译时类型是SuperClass,而运行时类型是PloymorphismTest001,当运行时调用该引用变量的方法时,其方法行为总是像子类方法的行为,而不是像父类方法行为,这将出现相同类型的变量、执行同一个方法时呈现出不同的行为特征,这就是多态。
特别提醒:
与方法不同的是,对象的属性则不具备多态性,如上面的sscc引用变量,程序中输出它的book属性时,并不是输出PloymorphismTest001类里定义的实例属性,而是输出SuperClass类的实例属性。
注意:
我们通过Object p = new Person()代码定义一个变量p,则这个p只能调用Object类的方法,而不能调用Person类里定义的方法。
Java中的继承、封装、多态的理解的更多相关文章
- java中的继承 和多态。
package com.aaa.zxf.ajax.test; /** *一. java 中的继承和多态. * * 继承的特性? * 1.实现继承的方式 * A 如何建立继承关系(一个类继承于 另一个类 ...
- 2017.10.10 java中的继承与多态(重载与重写的区别)
1. 类的继承 继承是面向对象编程技术的主要特征之一,也是实现软件复用的重要手段,使用继承特性子类(subclass) 可以继承父类(superclass)中private方法和属性,继承的目的是使程 ...
- 简谈java 中的 继承和多态
继承(extends) : 1:object 是所有类的父(基)类. 2:子类继承父类所有的内容除了(private修饰的和构造方法). 3:子类在手动创建构造方法时,必须调用父类构造方法. 4:在J ...
- Java中的继承和多态
1. 什么是继承,继承的特点? 子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承方法,使得子类具有父类相同的行为. 特点:在继承关系中,父类更通用.子类更具体.父类具有更 ...
- 【Java学习笔记之十六】浅谈Java中的继承与多态
1. 什么是继承,继承的特点? 子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承方法,使得子类具有父类相同的行为. 特点:在继承关系中,父类更通用.子类更具体.父类具有更 ...
- Python面向对象中的继承、多态和封装
Python面向对象中的继承.多态和封装 一.面向对象的三大特性 封装:把很多数据封装到⼀个对象中,把固定功能的代码封装到⼀个代码块, 函数,对象, 打包成模块. 这都属于封装思想. 继承:⼦类可以⾃ ...
- 【JAVA零基础入门系列】Day13 Java类的继承与多态
继承是类的一个很重要的特性,什么?你连继承都不知道?你是想气死爸爸好继承爸爸的遗产吗?(滑稽) 开个玩笑,这里的继承跟我们现实生活的中继承还是有很大区别的,一个类可以继承另一个类,继承的内容包括属性跟 ...
- OOP面向对象 三大特征 继承封装多态
OOP面向对象 ----三大特征 继承封装多态 面向对象(Object Oriented,OO)是软件开发方法.面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统.交互式界面.应用结构 ...
- java中的继承与oc中的继承的区别
为什么要使用继承? 继承的好处: (1)抽取出了重复的代码,使代码更加灵活 (2)建立了类和类之间的联系 继承的缺点: 耦合性太强 OC中的继承 1.OC中不允许子类和父类拥有相同名称的成员变量名:( ...
随机推荐
- LeetCode 1: single-number
Given an array of integers, every element appears twice except for one. Find that single one. soluti ...
- 01 Python简介、环境搭建及包管理(一)
一.Python简介 1. Python的特点: 是一门动态.解释型.强类型语言 动态:在运行期间才做数据检查(不用提前声明变量)- 静态语音(C/Java):编译时检查数据类型(编码时需要声明变量类 ...
- ReoGrid.Mvvm:ReoGrid绑定模型
ReoGrid 是 C# 编写的.NET 电子表格控件(类似 Excel).支持单元格合并,边框样式,图案背景颜色,数据格式,冻结,公式,宏和脚本执行,表格事件等.支持 Winform\WPF. Re ...
- Flask:对项目文件进行拆分
在工作中,我们不可能将ORM的配置,ORM的操作,ORM的使用以及视图放到同一个文件里,大多数时候Flask都是按照MVC的设计理念进行部署的 1.MVC和MTV (1)MVC(Model-View- ...
- 【GIT】下载最新库命令
使用技巧:使用这个命令 git clone git仓库地址 --depth=1 这样只下载最新版本仓库,而不是所有历史版本的仓库
- Alibaba Java Coding Guidelines,以后的Java代码规范,就靠它了
前言 对于Java代码规范,业界有统一的标准,不少公司对此都有一定的要求.但是即便如此,庞大的Java使用者由于经验很水平的限制,未必有规范编码的意识,而且即便经验丰富的老Java程序员也无法做到时刻 ...
- [考试反思]1011csp-s模拟测试69:无常
承蒙大脸skyh的毒奶,加之以被kx和Parisb以及板儿逼剥夺了一中午的睡眠(其实还有半个晚上)RP守恒终于失效了,连续两场没考好 RP也是不够了,竟然考原题,而且还不换题,连样例都一模一样只不过加 ...
- 【转载】InstantRun 原理——深度剖析 AndroidStudio 2.0
一.前言 Android Studio 2.0开始支持 Instant Run 特性, 使得在开发过程中能快速将代码变化更新到设备上.之前,更新代码之后需要先编译一个完整的新Apk,卸载设备上已安装的 ...
- JS中的两种数据类型以及实现引用类型的深拷贝
一.前言 我们知道,在JS中数据类型按照访问方式和存储方式的不同可分为基本类型和引用类型.基本类型基本类型有String.Boolean.Number,Undefined.Null,这些基本类型都是按 ...
- Kubernetes4-web管理界面
一.简介 1.环境 环境还是前面的环境 2.Kubernetes Dashboard web界面 kubernetes dashboard (仪表盘)是一个将通用的基于web的监控和操作界面加入kub ...