java中对shape进行封装,浅析 Java 三大特性封装, 继承, 多态, 及作业分析

浅析 Java 三大特性封装, 继承, 多态, 及作业分析

前言

本次博客衔接上次博客, 作为这一阶段 Java 学习的分析. 上一篇博客着重介绍了 Java 的 OO 编程思维, 面向对象与面向过程的区别. 本篇博客重心在 Java 的三大技术特性, 附带作业分析.

Java 三大特性

封装

在面向对象程式设计方法中, 封装是指一种将抽象性函式接口的实现细节部分包装, 隐藏起来的方法.

它将类的某些信息隐藏在类的内部, 不允许外部程序访问, 而是通过该类提供的方法来实现对隐藏信息的操作和访问.

实现封装的方式: 使用访问控制符

private 在当前类中可访问

default 在当前包内和访问

protected 在当前类和它派生的类中可访问

public 公众的访问权限, 谁都能访问

还有伴随着出现的还有 getter 和 setter 方法.(因知识面的原因, 相关的 package 和 import 先不讲解)

我们最常用的就是 private, 在继承中, 我们继承的也是父类的非 private 的属性和方法. 封装遵循了 "封闭原则", 禁止外部直接访问内部信息.

封装可以被认为是一个保护屏障, 防止该类的代码和数据被外部类定义的代码随机访问. 要访问该类的代码和数据, 必须通过严格的接口控制. 适当的封装可以让代码更容易理解与维护, 也加强了代码的安全性.

封装的优点:

1. 良好的封装能够减少耦合.

2. 类内部的结构可以自由修改.

3. 可以对成员变量进行更精确的控制.

4. 隐藏信息, 实现细节.

继承

继承是类之间的一种关系, 子类拥有父类非 private 的所有属性和方法, 从而实现了代码的复用. 继承是面向对象编程技术的基石, 它允许了创建分等级层次的类.

我们为什么要用继承?

举个例子:

我们拥有多个卡片, 现在需要输出每个卡片的形状, 那么没有继承之前我们可能是每一个卡片类之中书写 System.out.println("这张卡片的形状是 XXX"); 然而我们可以继承一个 Shape 类, Shape 类中写 show(){ System.out.println("这张卡片的形状是"+name);}这样代码的臃肿性就减少了, 而且后期维护性较高.

代码示例[1]

开发动物类其中动物分别为企鹅以及老鼠, 要求如下:

企鹅: 属性(姓名, id), 方法(吃, 睡, 自我介绍)

老鼠: 属性(姓名, id), 方法(吃, 睡, 自我介绍)

企鹅类publicclassPenguin{

privateStringname;

privateintid;

publicPenguin(StringmyName,intmyid){

name=myName;

id=myid;

}

publicvoideat(){

System.out.println(name+"正在吃");

}

publicvoidsleep(){

System.out.println(name+"正在睡");

}

publicvoidintroduction(){

System.out.println("大家好! 我是"+id+"号"+name+".");

}

}

老鼠类publicclassMouse{

privateStringname;

privateintid;

publicMouse(StringmyName,intmyid){

name=myName;

id=myid;

}

publicvoideat(){

System.out.println(name+"正在吃");

}

publicvoidsleep(){

System.out.println(name+"正在睡");

}

publicvoidintroduction(){

System.out.println("大家好! 我是"+id+"号"+name+".");

}

}

两行代码对比可以看出代码重复已经出现, 使得代码臃肿且后期维护性较低, 使用继承就能从根本上解决问题. 提取二者的重复部分建立一个公共父类

公共父类publicclassAnimal{

privateStringname;

privateintid;

publicAnimal(StringmyName,intmyid){

name=myName;

id=myid;

}

publicvoideat(){

System.out.println(name+"正在吃");

}

publicvoidsleep(){

System.out.println(name+"正在睡");

}

publicvoidintroduction(){

System.out.println("大家好! 我是"+id+"号"+name+".");

}

}

企鹅类publicclassPenguinextendsAnimal{

publicPenguin(StringmyName,intmyid){

super(myName,myid);

}

}

老鼠类publicclassMouseextendsAnimal{

publicMouse(StringmyName,intmyid){

super(myName,myid);

}

}

公共父类 Animal 拥有企鹅和老鼠类的相同属性和方法, 当企鹅和老鼠类继承公共父类之后, 子类也就不会再出现重复代码, 且代码的臃肿性降低, 可维护性升高.

我们也可以重写重写父类的方法, 及命名与父类同名的成员变量, 增加代码的灵活度. 我们重写的内容会覆盖掉父类的内容, 如果同时需要父类和子类的内容, 我们可以使用 super 与 this 关键字. 而 final 关键字声明类意义着不能继承, 即最终类; 或用于修饰方法, 不能被重写.

super 关键字: 我们可以通过 super 关键字来实现对父类成员的访问, 用来引用当前对象的父类.

this 关键字: 指向自己的引用.

super 和 this 代码示例[2]classAnimal{

voideat(){

System.out.println("animal : eat");

}

}

classDogextendsAnimal{

voideat(){

System.out.println("dog : eat");

}

voideatTest(){

this.eat();// this 调用自己的方法

super.eat();// super 调用父类方法

}

}

publicclassTest{

publicstaticvoidmain(String[]args){

Animala=newAnimal();

a.eat();

Dogd=newDog();

d.eatTest();

}

}

输出结果为:animal:eat

dog:eat

animal:eat

如果我们想尽可能的隐藏代码, 但是仍然允许子类的成员来访问它们. 这时候可以使用 protected.(关于继承权限的问题可能会在后续的学习中再进行补充)

关于继承 (extends) 和实现 (implement) 的区别

extends

1, 类的继承是单一继承, 也就是说, 一个子类只能拥有一个父类, 所以 extends 只能继承一个类.

2, 在继承中可以定义属性方法, 变量, 常量等...

Implement

1,Implement 可以有多个接口,(接口跟接口之间采用逗号分隔).

2, 在接口中只能定义全局常量(static final), 和空的方法体.

3, 某个接口被类实现时, 在类中一定要实现接口中的抽象方法.

继承类型[3]

ab7653affab982b574eb7acc55df2e04.gif

多态

概念: 多态是同一个行为具有多个不同表现形式或形态的能力.

Java 实现多态的三个必要条件: 继承, 重写, 向上转型

1, 继承: 在多态中必须存在有继承关系的子类和父类.

2, 重写: 子类对父类中某些方法进行重新定义, 在调用这些方法时就会调用子类的方法.

3, 向上转型: 在多态中需要将子类的引用赋给父类对象, 只有这样该引用才能够具备技能调用父类的方法和子类的方法.

使用多态的好处之一是当调用方法时, 先检查父类中是否拥有该方法, 如果没有则编译错误, 如果有, 再调用子类的同名方法. 使类的对象可以进行通用化处理, 同时增加了程序的延展性.

实现多态的方式

1, 基于继承实现的多态:

基于继承实现的多态主要是重写, 子类的重写. 多个子类的同一方法的重写可以表现出不同的行为.

2, 基于接口实现的多态:

基于接口实现的多态主要是实现接口并覆盖接口中同一方法的几不同的类体现的.

继承都是单继承, 只能为一组相关的类提供一致的服务接口. 但是接口可以是多继承多实现, 它能够利用一组相关或者不相关的接口进行组合与扩充, 能够对外提供一致的服务接口. 所以它相对于继承来说有更好的灵活性.

作业方面

这几次作业知识迭代正变得更加符合 Java 的三大技术特性, 不管是封装性还是继承性, 多态性, 这几次作业所给的 UML 类图也都能感觉到这些特性.

关于这几次作业的问题, 除了正则表达是以外就是关于 ArrayList 自定义类的的使用有所不理解.

例如 ArrayListlist 中能很简单的理解 Integer 的意义并简单的使用, 但是遇到了自定义的 ArrayList cardList 限定范围在自定义的 < Card > 类的范围以内, 就不知道如何是好, 其实理解并使用是一件比较简单事情, 像 integer 类型的 list.add(整型), 整型是是整数类型的数字, 而像 Card 类型的 list.add(卡片), 卡片是放入的卡片类的对象.1doubleradius=Main.input.nextDouble();

2Shapecircle=newCircle(radius);3Cardcard=newCard(circle);

4cardList.add(card);

// 简单的代码示例不做过多解释, 理解使用

网络上还有更加详细的 Arraylist 自定义类的教程, 比我浅薄的表达要好的多, 可以筛选并学习, 当学会了 Arraylist 自己定义类, 我感觉这两次的作业的难点也算是攻克了.

关于时间

这几次的作业花费时间最多的是水文测试的题目, 因为涉及正则表达式, 对于一个粗心的人来说, 学习并使用正则表达式简直就是噩梦. 花费时间最短的就是最近的一次作业, 原因也就是没有新的知识的扩展, 写起代码来也算是比较畅通.

关于测试

良好的测试并获取代码的信息式写好代码的必要条件, 随着代码长度及代码难度的增加测试的重要性也慢慢的体现了出来, 现在没有学会使用 Debug 的同学要开始加强学习了.

关于收获

这一阶段的收获一个是正则表达式的使用, 另一个就是 Java 三大技术特性封装, 继承, 多态的理解和使用.

关于课程建议

作业体量, 难度方面没有什么建议, 关于作业的建议就是更加详细点对作业中新出现的知识点进行讲解扩充, 也可以给予相关的教程方便后续的复习.

参考文献

[1][2][3]菜鸟教程 https://www.runoob.com/java/java-inheritance.html

来源: https://www.cnblogs.com/WangSIR-/p/java_two.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值