Java初学——面向对象的封装,继承,多态
Posted wuxuewei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java初学——面向对象的封装,继承,多态相关的知识,希望对你有一定的参考价值。
一、封装
1.为什要封装
封装的概念:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。把尽可能多的东西藏起来,对外提供便捷的接口。
封装的好处:便于使用者正确使用系统,防止错误修改属性 有助于系统之间的松耦合,提高系统独立性 提高软件的可重用性 降低了构建大型系统的风险。
封装的流程:
:
2.如何使用封装
在myexclipse中在已经建好的类中,按住快捷键Shift+Alt+S选择R 在弹出面板中选择要封装的成员变量。具体流程如图:
快捷键 Shift+Alt+S会出现如下图弹出界面 然后点击R
选择要封装的选项
点击ok,会生成get/set方法如图
或则选择myexlipse的工具栏Scoure---
二、继承
1.继承的相关属性
(1)在Java所有类都默认继承自Object,extends关键字实现类的继承。
(2)单根性:一个类只能存在一个父类在Java中的继承:子类可以继承父类的任何非私有成员(变量 方法 构造) 子类永远比父类拥有更多的成员,子>父。提升代码的复用性:减少代码的冗余
(3) Object:任意一个类都直接或间接继承Object 在MyEclipse中查看继承架构图的快捷键为ctrl+T ctrl+O 查看类中的所有成员
(4)native:不是由java实现的,而是由C语言实现的。
(5)final:常量 类(代表该类不能被继承) 方法(该方法不能被子类重写) 。
(6)方法重写:子类继承了父类的方法后,要对父类的方法进行改写 要求除了方法体之外,其他的必须一致(就进原则)。
(7)super:超类 super代表父类的对象。使用super关键字,super代表父类对象 ;在子类构造方法中调用且必须是第一句 ;不可以访问父类中定义为private的属性和方法如图:
2.继承条件下构造方法的调用规则
子类构造方法没有通过super显式调用父类的有参构造方法,也没通过this显式调用自身其他构造方法 系统默认调用父类的无参构造方法 子类构造方法通过super显式调用父类的有参构造方法 执行父类相应构造方法,而不执行父类无参构造方法 子类构造方法通过this显式调用自身的其他构造方法,在相应构造方法中应用以上两条规则
3.子类能继承什么
能继承public和protected修饰的属性和方法,不管子类和父类是否在同一个包里 继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包里。
不能继承父类中private成员,当子类与父类不在同包, 使用默认访问权限的成员。不能继承父类的构造方法。
三、多态
1.什么是多态
发生在具有继承关系的实体中,不同实体为了完成同一操作(函数名)所采取的不同方式(方法体)。在子类中方法重写:除方法体之外。其余完全一致
方法的重写或方法的覆盖:子类根据需求对从父类继承的方法进行重新编写 重写时,可以用super.方法的方式来保留父类的方法 构造方法不能被重写
2.方法重写是多态的基础
方法重写的规则:方法名相同 参数列表相同 返回值类型相同或者是其子类 访问权限不能严于父类 父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法 子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super) 父类的私有方法不能被子类覆盖 不能抛出比父类方法更多的异常。
方法重写和方法重载的区别:
3.面相对象设计八大原则
开-闭原则(目标、总的指导思想)对扩展开放,对修改关闭。增加新功能,不改变原有代码。
类的单一职责(一个类的定义)一个类有且只有一个改变它的原因。适用于基础类,不适用基于基础类构建复杂的聚合类。
依赖倒置(依赖抽象)客户端代码(调用的类)尽量依赖(使用)抽象的组件。抽象的是稳定的。实现是多变的。
组合复用原则(复用的最佳实践)如果仅仅为了代码复用优先选择组合复用,而非继承复用。组合的耦合性相对继承低。
里氏替换(继承后的重写,指导继承的设计)父类出现的地方可以被子类替换,在替换后依然保持原功能。 子类要拥有父类的所有功能。子类在重写父类方法时,尽量选择扩展重写,防止改变了功能。
接口隔离(功能拆分) 尽量定义小而精的接口interface,少定义大而全的接口。本质与单一职责相同。小接口之间功能隔离,实现类需要多个功能时可以选择多实现.或接口之间做继承。
面向接口编程而非面向实现(切换、并行开发)客户端通过一系列抽象操作实例,而无需关注具体类型。便于灵活切换一系列功能。
迪米特法则(类与类交互的原则)类与类交互时,在满足功能要求的基础上,传递的数据量越少越好。因为这样可能降低耦合度
4.多态实现的三种方式
父类类型接收子类对象实现的多态
父类类型作为方法形参
父类类型作为方法返回值
5.继承关系的引用数据类型转换
向上转型:子类对象--->父类做的转换 无需强转(没有异常)理论上和数据类型的强转和自转类似,向上转型就像int类型向double自动转形一样,子类本身会继承父类所有的非私有的成员变量和方法,并且还有自己的成员。所以子类转向父类是自动转换。
向下转型:父类类型--->子类类型转换 需要强转当父类向子类转换时有可能会运行报错,所以应用instanceof关 键词来规避如果能转换则会返回true,不能返回false。
6综合练习
以下代码运用抽象类 继承 封装 多态 类型转换 做的简单电子宠物购物系统(代码只是用于知识点的串联)
创建Pet父类
1 public abstract class Pet 2 private String name;//名字 3 private String sex;//性别 4 private int heathly;//健康值 5 private int qinmidu;//亲密度 6 abstract String leibieString(int i); //创建品种判断抽象方法 7 abstract void showinfo() ;//创建自我介绍抽象方法 8 abstract int zhiliao();//创建宠物治疗方法 让狗每次治疗健康值加十 企鹅每次治疗加5 9 //封装 10 public String getName() 11 return name; 12 13 public void setName(String name) 14 this.name = name; 15 16 public String getSex() 17 return sex; 18 19 public void setSex(String sex) 20 this.sex = sex; 21 22 public int getHeathly() 23 return heathly; 24 25 26 public void setHeathly(int heathly) 27 if (heathly<=100&&heathly>=0) 28 this.heathly=heathly; 29 else 30 this.heathly=60; 31 32 33 34 public int getQinmidu() 35 return qinmidu; 36 37 38 public void setQinmidu(int qinmidu) 39 if (qinmidu<=100&&qinmidu>=0) 40 this.qinmidu=qinmidu; 41 else 42 this.qinmidu=60; 43 44 45 46 47 48
创建子类dog
public class Dog extends Pet private String leibie; public String getLeibie() return leibie; public void setLeibie(String leibie) this.leibie = leibie; //实例化抽象方法 @Override String leibieString(int i) leibie=(i==1?"哈士奇":i==2?"京巴":"输入序号错误,请从新输入"); return leibie; @Override void showinfo() System.out.println("你好主人:我叫"+super.getName()+"我是:"+ super.getSex()+"我的健康值是:" +super.getHeathly()+"和主人的亲密度为"+super.getQinmidu()+"我的品种是"+this.getLeibie()); @Override int zhiliao() return (super.getHeathly()+10); public void play() System.out.println("经过强制转换我学会接飞镖");
创建Qie类
public class Qie extends Pet private String leibie; public String getLeibie() return leibie; public void setLeibie(String leibie) this.leibie = leibie; @Override String leibieString(int i) leibie=(i==1?"帝企鹅":i==2?"马达加斯加企鹅":"你的输入有误"); return leibie; @Override void showinfo() System.out.println("你好主人:我叫"+super.getName()+"我是:"+ super.getSex()+"我的健康值是:" +super.getHeathly()+"和主人的亲密度为"+super.getQinmidu()+"我的品种是"+this.getLeibie()); @Override int zhiliao() return (super.getHeathly()+5); public void eat() System.out.println("经过了强制转换我会吃鱼");
创建测试类
import java.util.Scanner; import com.sun.org.apache.bcel.internal.generic.INSTANCEOF; public class Pettest public static void main(String[] args) String ii; int i; Scanner inScanner=new Scanner(System.in); System.out.println("欢迎来到宠物医院!"); System.out.print("您的宠物种类是(1.狗狗2.企鹅)"); int q=inScanner.nextInt(); switch (q) case 1: Dog a=new Dog(); System.out.println("你的宠物名字是:"); ii=inScanner.next(); a.setName(ii); System.out.println("请输入性别(1.靓仔2.辣妹)"); i=inScanner.nextInt(); if(i==1) a.setSex("靓仔"); else if(i==2) a.setSex("辣妹"); else System.out.println("性别输入错误请从新输入"); i=inScanner.nextInt(); System.out.println("请选择品种1.哈士奇2.京巴"); i=inScanner.nextInt(); a.leibieString(i); System.out.println("请输入健康值"); i=inScanner.nextInt(); a.setHeathly(i); System.out.println("请输入亲密度"); i=inScanner.nextInt(); a.setQinmidu(i); a.showinfo(); System.out.println("经过治疗你的狗狗健康值为"+a.zhiliao()); // Pet bPet=new Dog(); // Dog d=(Dog)bPet; // d.play(); Pet bPet=new Dog(); //强制装换 if ( bPet instanceof Dog ) Dog d=(Dog)bPet; d.play(); break; case 2: Qie aa=new Qie(); System.out.println("你的宠物名字是:"); ii=inScanner.next(); aa.setName(ii); System.out.println("请输入性别(1.靓仔2.辣妹)"); i=inScanner.nextInt(); if(i==1) aa.setSex("靓仔"); else if(i==2) aa.setSex("辣妹"); else System.out.println("性别输入错误请从新输入"); i=inScanner.nextInt(); System.out.println("请选择品种1.帝企鹅2.马达加斯加企鹅"); i=inScanner.nextInt(); aa.leibieString(i); System.out.println("请输入健康值"); i=inScanner.nextInt(); aa.setHeathly(i); System.out.println("请输入亲密度"); i=inScanner.nextInt(); aa.setQinmidu(i); aa.showinfo(); System.out.println("经过治疗你的"+aa.getLeibie()+"健康值为"+aa.zhiliao()); Pet bQPet=new Qie(); //强制装换 if ( bQPet instanceof Qie ) Qie dD=(Qie)bQPet; dD.eat(); break; default: System.out.println("您的输入有误请从新输入"); break;
运行结果
以上是关于Java初学——面向对象的封装,继承,多态的主要内容,如果未能解决你的问题,请参考以下文章