Java面向对象 第3节 类的封装和继承
一、封装
- 封装的概念:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的访问和操作。
- 封装的2个大致原则:
1)把尽可能多的东西隐藏起来,对外提供便捷的接口
2)把所有的属性隐藏起来 - 封装的实现:
◆JAVA定义了4种访问权限:public (公有的)、protected(保护的)、private(私有的)和默认的
◆封装步骤
1)修改属性的可见性:设为private,防止错误修改
2)创建getter/setter方法:用于属性的读写
3)在getter/setter方法中加入属性控制语句:对属性值的合法性进行判断
4.使用封装的好处:
◆便于使用者正确使用系统,防止错误修改属性
◆有助于系统之间的松耦合,提高系统独立性
◆提高软件的可重用性
◆降低了构建大型系统的风险
package com.fengzhuang;
/*
*
* @author yutianbao
* @param
* @date 2019/3/13 22:04
* @return
* @Motto: good good study,day day up
*/
public class FengZhuang {
/*封装:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过
该类提供的方法来实现对隐藏信息的访问。*/
// 实现封装分三步
//1.修改属性的可见性:将属性私有化
private String name;
private int age;
private String phoneNo; //2.创建setter/getter方法
//给name赋值
public String getName() {
return this.name;
}
//取name值
public void setName(String name) {
this.name = name;
} public int getAge() {
return this.age;
}
//3.添加对属性操制作的限制
public void setAge(int age) {
if(age>0&&age<=150){
this.age = age;
}else{
System.out.println("您输入的年龄错误!");
this.age = 25;
}
}
public String getPhoneNo() {
return this.phoneNo;
}
public void setPhoneNo(String phoneNo) {
if(phoneNo.length()==11){
this.phoneNo = phoneNo;
}else{
System.out.println("您输入的手机号错误!");
this.phoneNo = "1xx xxxx xxxx" ;
}
}
public void print(){
System.out.println("我的名字是;"+this.getName()+",年龄是:"+this.getAge()+",手机号是:"+this.getPhoneNo());
} }
package com.fengzhuang;
/*
*
* @author yutianbao
* @param
* @date 2019/3/13 22:08
* @return
* @Motto: good good study,day day up
*/
public class Test {
public static void main(String[] args){
//FengZhuang fez = new FengZhuang("蒋辉煌",25,"18975742300");
FengZhuang fez = new FengZhuang();
fez.setName("余与");
fez.setAge(160);
fez.setPhoneNo("13632908564");
fez.print();
} }
二、继承
- 继承是一种由已有类创建新类的机制。利用继承,我们可以先创建一个共有属性的一般类,根据该一般类再创建具有特殊属性的新类。新类继承一般类的状态和行为,并根据需要增加它自己的状态和行为。
- 从现有类出发定义一个新类,称为新类继承了现有的类,其中被继承的现有类叫做超类(superclass)或父类,由继承而得到的类称为子类(subclass)。
- Java中规定,一个父类可以同时拥有多个子类,但一个子类只能有一个父类,即单重继承,而且允许多层继承,即子类还可以有它自己的子类,在下一层的继承关系中原先的子类就变成了父类。这样的继承关系就形成了继承树。
1、类继承用关键字extends实现,格式为:[访问权限修饰符] class 子类名 extends 父类名{ 子类的类体 }
如果没有extends子句,则表示这个类直接继承Object,因为Java中所有的类都继承Object类。
2、成员变量的继承
子类继承父类中所有可被子类访问的成员变量。继承原则如下:
2.1 能够继承那些声明为public和protected的成员变量。
2.2 能够继承同一包中的那些默认修饰符的成员变量。
2.3 不能继承那些声明为private的成员变量。
2.4 如果子类声明一个与父类成员变量同名的成员变量,则不能继承父类的成员变量。此时子类的成员变量称做隐藏了父类的成员变量。
总之,子类可继承父类的public、protected和默认修饰变量,不能继承private变量。反之,如果父类不允许其子类访问它的某些成员,那么它必须以private方式声明该成员。这一点充分体现了类封装的信息隐蔽原则。
3、成员方法的继承
子类继承成员方法的规则类似于继承成员变量的规则:子类继承父类中所有可被子类访问的成员方法。继承规则如下:
3.1 能够继承那些声明为public和protected的成员方法。
3.2 能够继承同一包中的默认修饰符的成员方法。
3.3 不能继承那些声明为private的成员方法。
3.4 不能继承父类的构造方法。
如果子类方法与父类方法同名,则不能继承。子类方法称为覆盖(或重写)了父类中的那个方法。
总之,子类可继承其父类的public、protected和默认修饰方法,不能继承private方法。子类除了可以继承父类中的变量及方法,还可以增加自己的成员。当一个父类成员不适合该子类时,子类会重新定义它,如果是重新定义的是成员变量就是隐藏父类的变量,如果是成员方法就是覆盖父类的方法。
package com.extend;
/**
* 宠物类,狗狗和企鹅的父类
*/
public class Pet {
private String name = "无名氏";// 昵称
private int health = 100;// 健康值
private int love = 20;// 亲密度 /**
* 无参构造方法
*/
public Pet() {
System.out.println("父类无参构造方法");
}
/**
* 有参构造方法
* @param name 昵称
*/
public Pet(String name,int health,int love) {
this.name = name;
this.health = health;
this.love = love;
System.out.println("父类有参构造方法");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getHealth() {
return health;
} public void setHealth(int health) {
if(health<0||health>100){
System.out.println("健康值应该在0至100之间,默认值为60。");
this.health=60;
return;
}
this.health = health;
} public int getLove() {
return love;
} public void setLove(int love) {
if(love<0||love>100){
System.out.println("亲密度应该在0至100之间,默认值为10。");
this.love=10;
return;
}
this.love = love;
} /**
* 输出宠物信息
*/
public void print() {
System.out.println("宠物的自白:\n我的名字叫" +
this.name + ",我的健康值是" + this.health
+ ",我和主人的亲密程度是" + this.love + "。");
} //重写Object类的equals()方法
public boolean equals(Object obj){
boolean flag = false;
if(obj==this){ //==比较引用地址
flag = true;
}
if(!(obj instanceof Pet)){ //instanceof 判断类型
flag = false;
}else{
Pet pe = (Pet)obj;
if(pe.love==this.love&&pe.health==this.health&&pe.love==this.love){
flag = true;
}
}
return flag;
}
}
package com.extend;
/**
* 狗狗类,宠物的子类
*/
public class Dog extends Pet {
private String strain="哈士奇";// 品种 //无参构造方法
public Dog(String name,int health,int love,String strain) {
super(name,health,love);
this.strain = strain;
System.out.println("dog类构造方法");
} public String getStrain() {
return strain;
} public void setStrain(String strain) {
this.strain = strain;
}
//重写父类方法
public void print() {
System.out.println("宠物的自白:\n我的名字叫" +
this.getName() + ",我的品种是" + this.getStrain()+",我的健康值是" + this.getHealth()
+ ",我和主人的亲密程度是" + this.getLove() + "。");
}
}
package com.extend; import com.sun.jmx.snmp.SnmpString; /**
* 企鹅类
*/
public class Penguin extends Pet {
private String sex="Q仔";// 企鹅性别 //构造方法
public Penguin(String name,int health,int love,String sex) {
super(name,health,love);
this.sex = sex;
System.out.println("penguin类构造方法");
} public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
//重写父类方法
public void print() {
System.out.println("宠物的自白:\n我的名字叫" +
this.getName() + ",我的性别是" + this.getSex()+",我的健康值是" + this.getHealth()
+ ",我和主人的亲密程度是" + this.getLove() + "。");
} }
package com.extend;
//测试类
public class Test {
public static void main(String[] args) {
// 1、创建宠物对象pet并输出信息
Pet pet = new Pet("贝贝",99,60);
//Pet pet1 = new Pet("贝贝",99,60);
//Pet pet2 = new Pet("贝贝",99,59);
//System.out.println("equals()比较对象:"+pet1.equals(pet2));
pet.print();
// 2、创建狗狗对象dog并输出信息
Dog dog = new Dog("贝贝",59,40,"牧羊犬");
// dog.setName("多多");
// dog.setHealth(90);
// dog.setLove(80);
// dog.setStrain("吉娃娃");
dog.print();
// 3、创建企鹅对象pgn并输出信息
Penguin pgn = new Penguin("幽幽",85,20,"Q妹");
// pgn.setName("大黑");
// pgn.setHealth(98);
// pgn.setLove(99);
// pgn.setSex("Q妹");
pgn.print(); /**************************/
// Bus bus = new Bus(20);
// bus.print();
//System.out.println(pgn.equals(dog));
}
}
4.子类访问父类成员
在数据隐藏和方法覆盖后,子类成员覆盖了父类的同名成员,要访问父类的这些成员,需用super关键字来引用当前类的父类。super的用法有3种情况:
4.1 super.变量名:访问父类中被隐藏的成员变量。
4.2 super.方法名([参数表]):调用父类中被重写的方法。
4.3 super([参数表]):调用父类的构造方法,此时,可用super来表示父类的构造方法。
例子可以参考上面继承的代码
5.继承条件下的构造方法
package com.extend;
//测试类
class Car{
private int siteNo = 4;//载客量
public Car(){
System.out.println("载客量是:"+siteNo+"人");
}
public void setSiteNo(int siteNo){
this.siteNo = siteNo;
}
public void print(){
System.out.println("载客量是:"+siteNo+"人");
}
}
class Bus extends Car{
public Bus(int siteNo){
setSiteNo(siteNo);
}
}
public class Test {
public static void main(String[] args) {
Bus bus = new Bus(20);
bus.print();
}
}
5、重写
◆重写是指在继承过程中,子类中的成员(包括数据和方法)与其父类中的成员同名,但功能不同,此时,子类的成员“覆盖”从父类继承过来的成员。包括两种情况:
一是数据覆盖,称为数据隐藏,即父、子类中数据成员的名称相同,类型不同,它们实际上是完全不同的两个数据;
二是方法覆盖,称为方法重写,即父、子类中方法的名称相同,参数表也完全相同,但功能不同。
◆方法重写和方法重载的区别
6.Object类的equals()方法
Java面向对象 第3节 类的封装和继承的更多相关文章
- Java面向对象 第1节 类和对象
一.Java 对象和类 面向对象语言三大特性:封装.继承.多态: 对象:描述客观事物的一个实体: 类:类是封装对象的属性和方法的载体,反过来说具有相同属性和行为的一类实体被称为类:类行为:方法:属性: ...
- Java面向对象概述及三大特征(封装,继承和多态)
一.面向对象思想 Java是面向对象的高级语言,对于Java语言来说,万事万物皆对象! 它的基本思想是使用类,对象,继承,封装,消息等基本概念进行程序设计.面向对象程序的最小单元是类,类代表了客观世界 ...
- Java面向对象 第4节 类的多态性
一.多态的概念 在面向对象语言中,多态是指在一棵继承树中的类中可以有多个同名但不同方法体及不同形参的方法.通常有两种途径实现多态:方法的重载和覆盖. 多态性允许以统一的风格处理已存在的变量及相关的类. ...
- Kotlin——从无到有系列之中级篇(四):面向对象的特征与类(class)继承详解
如果您对Kotlin很有兴趣,或者很想学好这门语言,可以关注我的掘金,或者进入我的QQ群大家一起学习.进步. 欢迎各位大佬进群共同研究.探索 QQ群号:497071402 进入正题 在前面的章节中,详 ...
- java类的封装、继承、多态
一.封装(encapsulation) 封装性就是把类(对象)的属性和行为结合成一个独立的相同单位,并尽可能隐蔽类(对象)的内部细节,对外形成一个边界,只保留有限的对外接口使之与外部发生联系.封装的特 ...
- 牛客网Java刷题知识点之面向对象java的四大特性(抽象、封装、继承、多态)
不多说,直接上干货! 面向对象java的四大特性之抽象 抽象就是有点模糊的意思,还没确定好的意思. 就比如,要定义一个方法和类.但还没确定怎么去实现它的具体一点的子方法,那我就可以用抽象类或接口.具体 ...
- Java面向对象(一)类和对象
面向过程和面向对象的区别 面向过程,强调的是功能行为,是将实现一个功能的步骤编写在一个函数中,以函数为最小单位. 面向对象,是将需要的功能封装进一个对象中,使一个对象具有很多的功能特征,以类/对象为最 ...
- Java—类的封装、继承与多态
一.类和对象 1.类 类是数据以及对数据的一组操作的封装体. 类声明的格式: 类声明 { 成员变量的声明: 成员方法的声明及实现: } 1.1 声明类 [修饰符] class 类<泛型> ...
- Python面向对象编程-类的封装,继承、多态
面向对象是一种程序设计思想,对象作为程序基本单元,包含了数据和操作数据的函数. 面向对象的三大特点--数据封装.多态和继承. #类的创建,class关键字,类名大写,object表示从哪个类继承而来, ...
随机推荐
- asp.net mvc session锁问题
一.会话状态Session Session用于服务器端状态管理,使用Session之后,每个客户端都可以将实际的数据保存在服务器上,对于每个客户端的数据,将会生成一个对应的唯一的key(保存在客户端) ...
- kafka生产者
1.kafka生产者是线程安全的,她允许多个线程共享一个kafka实例 2.kafka管理一个简单的后台线程,所有的IO操作以及与每个broker的tcp连接通信,如果没有正确的关闭生产者可能会造成资 ...
- vue-循环并获取dom元素
<ul class="picBox"> <li v-for="(item,index) in picArr" ><img :src ...
- Dagger2
一.理解Dagger2原理 原文链接 二.Dagger2例子实战 原文链接 Demo地址 注:关于错误:IncompleteAnnotationException: dagger.Provides m ...
- linux下NFS实战
系统环境 系统平台:CentOS release 6.8 (Final) NFS Server IP:172.16.55.6 防火墙关闭 SELinux=disabled 安装NFS程序包 1.查看系 ...
- Oracle 11g streams部署
环境 源服务器 目标服务器 系统版本 CentOS Linux release 7.3.1611 (Core) CentOS Linux release 7.3.1611 (Core) 主机名 s ...
- 2015-10-13 jQuery5实例
jQuery(5) 一.扑克牌切换 <body> <div class="ig ig1"><img src="image/1.jpg&q ...
- angular学习2
1.为了在angular里面使用bootstrap,可以如下操作 (1)停止正在运行的终端指令:ctrl+c (2)在终端里面输入:npm install bootstrap --save (3)在V ...
- Python爬虫之requests
爬虫之requests 库的基本用法 基本请求: requests库提供了http所有的基本请求方式.例如 r = requests.post("http://httpbin.org/pos ...
- C++开发者都应该使用的10个C++11特性 转
http://blog.jobbole.com/44015/// | 分类: C/C++, 开发 | 条评论 | 标签: C++, C语言 分享到: 本文由 伯乐在线 - 治不好你我就不是兽医 翻译自 ...