java类的封装、继承、多态
一、封装(encapsulation)
封装性就是把类(对象)的属性和行为结合成一个独立的相同单位,并尽可能隐蔽类(对象)的内部细节,对外形成一个边界,只保留有限的对外接口使之与外部发生联系。封装的特性使得类(对象)以外的部分不能随意存取类(对象)的内部数据(属性),保证了程序和数据不受外部干扰且不被误用。
这个怎么理解呢?首先来看一个列子。
已知一个类Animal,该类的属性和方法如下表所示:
属性 |
说明 |
方法 |
说明 |
String name |
名称 |
Animal() |
无参构造函数,为属性设置初始值 |
Int age |
年龄 |
Animal(String name,int age) |
有参构造函数,为属性设置变量值 |
根据该类的定义,编写一个程序,输出该类的初始值以及通过变量设置的初始值,程序代码如下
public class AnimalDemo{
public static void main(Stringargs[]){
Animal a=new Animal();
Animal b=new Animal("cat",5);
System.out.println(a.name+"is "+a.age+" years old");
System.out.println(b.name+"is "+b.age+" years old");
}
}
程序执行结果:
Dog is 3 years old
cat is 5 years old
由此可以知道,类Animal的无参构造函数为name属性赋值为“Dog”,为age属性赋值为“3”。因此,可以写出类Animal的代码如下:
class Animal {
String name;
int age;
Animal(){
name="Dog";
age=3;
}
Animal(Stringname,int age){
this.name=name;
this.age=age;
}
}
实际上这就是上一篇文章中的例子,那么封装在这里的含义如下:
l 类本身就实现了封装功能,此处类Animal定义了两个属性,两个构造函数,其只属于Animal类。
l 通过访问修饰符来限制对类的属性和方法的访问,各修饰符含义如下:
Private:成员变量和方法只能在类内被访问,具有类可见性
默认: 成员变量和方法只能被同一个包里的类访问,具有包可见性。
Protected:可以被同一个包中的类访问,被同一个项目中不同包中的子类访问
Public:可以被同一个项目中所有的类访问,具有项目可见性,这是最大的访问权限
l 只能通过类本身定义的方法来对该类所实例化的对象进行数据的访问和处理。比如想对实例化的对象添加其它的一个方法和属性是不可能的。这就体现的类的封装性。这里也可以理解一下为什么类被称之为模板或者蓝图。
二、继承
1、继承是面向对象的三大特征之一,也是实现代码复用的重要手段。Java的继承具有单继承的特点,即只能继承自一个父类,每个子类只有一个直接父类,但是其父类又可以继承于另一个类,从而实现了子类可以间接继承多个父类,但其本质上划分仍然是一个父类和子类的关系。
2、Java的继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类称为父类(有的也称其为基类、超类),父类和子类的关系,是一种一般和特殊的关系。就像是水果和苹果的关系,苹果继承了水果,苹果是水果的子类,水果是苹果的父类,则苹果是一种特殊的水果。
3、Java使用extends作为继承的关键字,extends关键字在英文是扩展的意思,而不是继承。为什么国内把extends翻译成继承呢?除了与历史原因有关外,把extends翻译成为继承也是有其道理的:子类扩展父类,将可以获得父类的全部属性和方法,这与汉语中得继承(子辈从父辈那里获得一笔财富成为继承)具有很好的类似性。
值得指出的是:Java的子类不能获得父类的构造器。
创建子类一般形式如下:
class 类名 extends 父类名{
子类体
}
4、子类与父类的变量、方法关系
子类可以继承父类的所有特性,但其可见性,由父类成员变量、方法的修饰符决定。对于被private修饰的类成员变量或方法,其子类是不可见的,也即不可访问;对于定义为默认访问(没有修饰符修饰)的类成员变量或方法,只有与父类同处于一个包中的子类可以访问;对于定义为public或protected 的类成员变量或方法,所有子类都可以访问。
子类中可以声明与父类同名的成员变量,这时父类的成员变量就被隐藏起来了,在子类中直接访问到的是子类中定义的成员变量。
子类中也可以声明与父类相同的成员方法,包括返回值类型、方法名、形式参数都应保持一致,称为方法的覆盖。
如果在子类中需要访问父类中定义的同名成员变量或方法,需要用的关键字super。Java中通过super来实现对被隐藏或被覆盖的父类成员的访问。super 的使用有三种情况:
l 访问父类被隐藏的成员变量和成员方法;
super.成员变量名;
l 调用父类中被覆盖的方法,如:
super.成员方法名([参数列]);
l 调用父类的构造函数,如:
super([参数列表]);
super( )只能在子类的构造函数中出现,并且永远都是位于子类构造函数中的第一条语句。
举例:
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();
}
}
举例二:
class Animal {
String name="animal";
int age;
void move(){
System.out.println("animalmove");
}
}
classDog extends Animal{
String name="dog"; //隐藏了父类的name属性;
float weight; //子类新增成员变量
void move(){ //覆盖了父类的方法move()
super.move(); //用super调用父类的方法
System.out.println("Dog Move");
}
}
publicclass InheritDemo{
public static void main(String args[]){
Dog d=new Dog();
d.age=5;
d.weight=6;
System.out.println(d.name+" is"+d.age+" years old");
System.out.println("weight:"+d.weight);
d.move();
}
}
程序运行结果:
dog is5 years old
weight:6.0
animalmove
DogMove
举例三:
classSuperClass {
SuperClass() {
System.out.println("调用父类无参构造函数");
}
SuperClass(int n) {
System.out.println("调用父类有参构造函数:" + n );
}
}
classSubClass extends SuperClass{
SubClass(int n) {
System.out.println("调用子类有参构造函数:" + n );
}
SubClass(){
super(200);
System.out.println("调用子类无参构造函数");
}
}
publicclass InheritDemo2{
public static void main(String arg[]) {
SubClass s1 = new SubClass();
SubClass s2 = new SubClass(100);
}
}
程序运行结果:
调用父类有参构造函数:200
调用子类无参构造函数
调用父类无参构造函数
调用子类有参构造函数:100
请自行分析程序运行的结果,体会继承的用法。
三、多态(Polymorphism)
多态性是指在继承关系中的父类中定义的属性或方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或方法在父类及其各子类类中具有不同的含义。
Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时的类型由声明该变量时使用的类型决定,运行时的类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就会出现所谓的多态(Polymorphism)
举例1:
class Animal2 {
void eat(){
System.out.println("animal eat");
}
}
class Dog extends Animal2 {
void eat(){
System.out.println("Dog eat bone");
}
}
class Cat extends Animal2 {
void eat(){
System.out.println("Cat eat fish");
}
}
public class PloyDemo{
public static void main(String args[]){
Animal2 a;
a=newAnimal2 (); //编译时类型和运行时类型完全一样,因此不存在多态
a.eat();
a=new Dog(); //下面编译时类型和运行时类型不一样,多态发生
a.eat();
a=new Cat(); //下面编译时类型和运行时类型不一样,多态发生
a.eat();
}
}
程序运行结果:
animal eat
Dog eat bone
Cat eat fish
实例2:
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 Stringbook = "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()
子类中覆盖父类的方法
java类的封装、继承、多态的更多相关文章
- java类的封装 继承 多态
1.猜数字小游戏 package cn.jiemoxiaodi_02; import java.util.Scanner; /** * 猜数字小游戏 * * @author huli * */ pub ...
- java面向对象(封装-继承-多态)
框架图 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向对象的特点 ...
- Java三大特性(封装,继承,多态)
Java中有三大特性,分别是封装继承多态,其理念十分抽象,并且是层层深入式的. 一.封装 概念:封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据 ...
- Java基础——面向对象(封装——继承——多态 )
对象 对象: 是类的实例(实现世界中 真 实存在的一切事物 可以称为对象) 类: 类是对象的抽象描述 步骤: 1.定义一个类 (用于 描述人:) ( * 人:有特征和行为) 2.根据类 创建对象 -- ...
- php面向对象 封装继承多态 接口、重载、抽象类、最终类总结
1.面向对象 封装继承多态 接口.重载.抽象类.最终类 面向对象 封装继承多态 首先,在解释面向对象之前先解释下什么是面向对象? [面向对象]1.什么是类? 具有相同属性(特征)和方法(行为)的一 ...
- 浅谈学习C++时用到的【封装继承多态】三个概念
封装继承多态这三个概念不是C++特有的,而是所有OOP具有的特性. 由于C++语言支持这三个特性,所以学习C++时不可避免的要理解这些概念. 而在大部分C++教材中这些概念是作为铺垫,接下来就花大部分 ...
- Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态)
Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态) 1.面向对象的三大特性: (1)继承 继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,父类又可以 ...
- OOP三大核心封装继承多态
OOP支柱 3 个核心:封装 继承 多态 封装就是将实现细节隐藏起来,也起到了数据保护的作用. 继承就是基于已有类来创建新类可以继承基类的核心功能. 在继承中 另外一种代码重用是:包含/委托,这种重用 ...
- python面向对象(封装,继承,多态)
python面向对象(封装,继承,多态) 学习完本篇,你将会深入掌握 如何封装一个优雅的借口 python是如何实现继承 python的多态 封装 含义: 1.把对象的属性和方法结合成一个独立的单位, ...
- Java—类的封装、继承与多态
一.类和对象 1.类 类是数据以及对数据的一组操作的封装体. 类声明的格式: 类声明 { 成员变量的声明: 成员方法的声明及实现: } 1.1 声明类 [修饰符] class 类<泛型> ...
随机推荐
- EBS OAF中如何在多行表中实现附件功能
EBS OAF中如何在多行表中实现附件功能 (版权声明,本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处:否则请与本人联系,违者必究) 在OAF中使用附件功能之前,要先明白Entity( ...
- Linux网络管理——端口作用
1. 网络基础 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB",&q ...
- C语言如何定义结构体
原文地址 1. struct与typedef struct区别 struct是结构体的关键字,用来声明结构体变量如 struct student { char num[10]; ch ...
- 点语法、property、self注意
1.点语法(找出不合理的地方)#import <Foundation/Foundation.h>@interface Person : NSObject{ int _age;}- ( ...
- sqlite3编译与查询
1.sqlite3 http://www.sqlite.org/ 下载 wget http://www.sqlite.org/2014/sqlite-amalgamation-3080403.zip ...
- Linux中的cron计划任务配置方法(详细)
cron来源于希腊单词chronos(意为“时间”),指Linux系统下一个自动执行指定任务的程序(计划任务) 1. crontab命令选项 #crontab -u <-l, -r, -e> ...
- SpringMVC 中整合之JSON、XML
每次看到好的博客我就想好好的整理起来,便于后面自己复习,同时也共享给网络上的伙伴们! 博客地址: springMVC整合Jaxb2.xStream: http://www.cnblogs.com/h ...
- 柯南君:看大数据时代下的IT架构(8)消息队列之RabbitMQ--案例(topic起航)
二.Topic(主题) (using the Java client) 上一篇文章中,我们进步改良了我们的日志系统.我们使用direct类型转发器,使得接收者有能力进行选择性的接收日志,,而非fano ...
- 2016 Multi-University Training Contest 1 总结
算是组队后第一次打比赛吧. 09题开始就有人过了,看到题目,这不是轮廓线DP的裸题么?!!,一发WA告终,然后发现题目是有改动的.还是太心急了. 然后我读了第一题,是最小生成树求期望距离,我把题意说了 ...
- Eclipse无法识别(手机)设备的解决方案
遇到问题 开始学习android一个多月了,用Eclipse开发,用android手机调试.之前一直好好的,突然Eclipse无法识别手机设备了.纠结了好久,找了各种解决方法,弄了一晚上终于解决问题了 ...