一、问题

最近在写代码,有两个属性很相近的类,其中80%的属性(字段)都是一样的,剩下的才是各自不一样的,在设计的时候,采用了继承的方式,抽象除了一个父类,大概如下,

有FirstChild和SecondChild两个类,因为其中的属性name、code等是相同的,为此抽出了一个父类BaseDO,如下

package com.example.day01;

public class BaseDO {
private String name;
private String code;
private String field1;
private String field2; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getCode() {
return code;
} public void setCode(String code) {
this.code = code;
} public String getField1() {
return field1;
} public void setField1(String field1) {
this.field1 = field1;
} public String getField2() {
return field2;
} public void setField2(String field2) {
this.field2 = field2;
} @Override
public String toString() {
return "BaseDO{" +
"name='" + name + '\'' +
", code='" + code + '\'' +
", field1='" + field1 + '\'' +
", field2='" + field2 + '\'' +
'}';
}
}

FirstChild

package com.example.day01;

public class FirstChild extends BaseDO{
private String myField1;
private String myFiled2; public String getMyField1() {
return myField1;
} public void setMyField1(String myField1) {
this.myField1 = myField1;
} public String getMyFiled2() {
return myFiled2;
} public void setMyFiled2(String myFiled2) {
this.myFiled2 = myFiled2;
} @Override
public String toString() {
return "FirstChild{" +
"myField1='" + myField1 + '\'' +
", myFiled2='" + myFiled2 + '\'' +
"} " + super.toString();
}
}

SecondChild

package com.example.day01;

public class SecondChild extends BaseDO{
private String secondField1;
private String secondField2; public String getSecondField1() {
return secondField1;
} public void setSecondField1(String secondField1) {
this.secondField1 = secondField1;
} public String getSecondField2() {
return secondField2;
} public void setSecondField2(String secondField2) {
this.secondField2 = secondField2;
} @Override
public String toString() {
return "SecondChild{" +
"secondField1='" + secondField1 + '\'' +
", secondField2='" + secondField2 + '\'' +
"} " + super.toString();
}
}

从上面可以看到两个子类除了含有父类的属性外还有自己各自的属性,现在有个需求是这样的,要实例化这两个子类。

二、如何解决

2.1、分别初始化

何为分别初始化,所谓分别初始化就是各自初始化自己的,为每个子类分别实现初始化其属性的方法,如下

FirstChild fillFirstField(FirstChild firstChild){

        firstChild.setName("apple");
firstChild.setCode("apple");
firstChild.setMyField1("first Child"); return firstChild;
}
SecondChild fillSecondField(SecondChild secondChild){

        secondChild.setName("apple");
secondChild.setCode("apple");
secondChild.setSecondField1("second Child");
return secondChild;
}

这里作为演示对属性没有全部赋值,如果两个子类相同的属性比较多,那么赋值起来会比较麻烦,而且两个方法的代码重复度会很高。

2.2、抽象出一个公共的方法

既然,已经为两个子类抽象出了公共的属性,那么顺着这个思路下去,也可以抽象出一个公共的方法为这些公共的属性赋值,即为父类填充属性,

BaseDO fillField(BaseDO baseDO){
baseDO.setName("apple");
baseDO.setCode("apple");
return baseDO;
}

好了,在进行子类初始化的时候已经有一个方法可以初始化其公共属性,那么接下来的事情,就是初始化其自己的属性即可,

下面就实例化FirstChild,然后初始化其公有属性

FirstChild firstChild=new FirstChild();
fillField(firstChild);
firstChild.setMyField1("first Child");
System.out.println(firstChild);

打印出firstChild的结果如下

可以看到已经把公共属性name、code和特意属性myField1进行赋值,完成了上面的需求。

可能有些同学会使用下面的写法,

可以看的该种写法存在错误,提示我们需要的类型是FirstChild,但是我们提供的BaseDO,我们知道fillField方法返回的BaseDO类型,一个父类型的实例不可赋值给子类型的引用(相反一个子类型的实例可以赋值给父类型,典型的多态),这怎么办那,向下类型转换,没错,如下

细心的小伙伴会问,那为什么fillField方法可以接受FirstChild的实例那,哈哈哈,前边红字提到了多态。

怎么样,是不是对多态又有了更深的理解。

延申一点

从fillField方法来看,我们知道该方法可以不设返回值,为什么可以不设返回值,因为引用类型,不是传值,可以理解为引用,哈哈,所以叫引用类型,在fillField方法中对其引用类型的参数进行了修改,那么在这个方法执行完了之后,引用这个参数的其他引用同样可以感知到其修改,下面的写法就是很好的佐证,

是不是又加深了引用和引用的对象间的关系,多说一句引用在jvm的内存模型中是在哪个区,引用指向的对象那?

三、总结

本文分析了在开发过程中,遇到公有属性很多的多个实体类时的设计思路,抽出公有的父类,由父类承担公有属性。并且在进行属性填充的时候,如果公有属性的值是一样的,那么可以抽出公共的方法进行属性填充,这里又提到了多态。

1、抽出公有属性;

2、对多态的理解;

3、向下类型转换;

4、引用类型的传递;

最后,广大读者们,对于类似的需求,你们有更好的设计思路吗,欢迎踊跃讨论。

在java的继承中你是否有这样的疑惑?的更多相关文章

  1. Java关于继承中的内存分配

    1.定义         super:当前对象的父类对象         this   :当前对象,谁调用this所在的方法,this就是哪一个对象.   2.内存分析 另一个例子: public s ...

  2. java之继承中的构造方法

    继承中的构造方法  1.子类的构造过程中必须调用其基类的构造方法. 2.子类可以在自己的构造方法中使用super(argument_list)调用基类的构造方法. 2.1.使用this(argumen ...

  3. java的继承中构造方法

    构造方法在创建对象的时候是被自动调用的,然后在继承中,是先调用父类的构造方法,然后在调用子类的构造方法, 当构造方法重写之后,在super中添加对应你想要调用构造方法的参数 例:父类 package ...

  4. java之继承中的静态变量

    package Test; /** * Created by wangbin10 on 2018/7/9. * 我们知道静态变量属于类级别变量,对应每个类只有一份,类的所有实例共有一份,而成员变量则分 ...

  5. java在继承中父类的成员变量是否会被子类所覆盖

    假如 父类 int num =7:子类 int num =9:父类是否会被子类所覆盖? 给你看两个例子: 第一个例子: 第二个例子: 这两个例子的区别只有一句话   由此证明了子类从父类继承的时候   ...

  6. JAVA基础--继承中的构造方法

    1. 子类的构造方法必须调用父类的构造方法 2. 子类在自己的构造方法中使用super(argument_list)调用父类的构造方法, 使用this(argument_list)调用自己的其他的构造 ...

  7. c++  与  java  中的 继承

    C++ 代码: #include <iostream> #include <string> using namespace std; class Parent { public ...

  8. Java多态机制和继承中重写重载

    关于Java中多态机制 http://www.cnblogs.com/chenssy/p/3372798.html 这篇博文讲的很透彻 大体意思是 多态定义: 多态就是指程序中定义的引用变量所指向的具 ...

  9. [Java] 继承中,父类被覆盖的成员变量、方法的可访问性

    在 Java 的继承机制里,在子类内部,可以访问父类被覆盖的变量和方法:在子类外部,可以访问父类的被覆盖变量,但是不能访问父类的被覆盖方法. 父类中被覆盖的方法不能在外部被方法,这是出于封装的考虑. ...

随机推荐

  1. NOI Online 2021 入门组 T1

    Description 题目描述 Alice.Bob 和 Cindy 三个好朋友得到了一个圆形蛋糕,他们打算分享这个蛋糕. 三个人的需求量分别为 \(a, b, c\),现在请你帮他们切蛋糕,规则如下 ...

  2. Redis 学习笔记(四)RDB 和 AOF 持久化机制

    一.Redis 持久化简介 Redis 的持久化功能是区别于 Memcached 显著特性,数据持久化可以保证系统在发生宕机和重启后数据不会丢失,对于 redis 这种存储在内存中的数据库显得尤为重要 ...

  3. ApacheCN 深度学习译文集 20210125 更新

    新增了七个教程: PyTorch 中文官方教程 1.7 学习 PyTorch PyTorch 深度学习:60 分钟的突击 张量 torch.autograd的简要介绍 神经网络 训练分类器 通过示例学 ...

  4. JavaCV的摄像头实战之五:推流

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<JavaCV的摄像头实战> ...

  5. MySQL不建议delete删除数据

    InnoDB存储架构 从这张图可以看到,InnoDB存储结构主要包括两部分:逻辑存储结构和物理存储结构. 逻辑上是由表空间tablespace -> 段segment或者inode -> ...

  6. JS 高阶函数

    笔记整理自:廖雪峰老师的JS教程 目录 概述 Array中的高阶函数 map(返回新的Array) reduce(返回新的Array) filter(返回新的Array) sort(返回同一Array ...

  7. Shell循环练习题

    Shell循环练习题 目录 Shell循环练习题 1.计算从1到100所有整数的和 2.提示用户输入一个小于100的整数,并计算从1到该数之间所有整数的和 3.求从1到100所有整数的偶数和.奇数和 ...

  8. iframe父子页面相互调用方法,相互获取元素

    父页面获取子页面 var childWin = document.getElementById('setIframe').contentWindow;//获取子页面窗口对象 childWin.send ...

  9. 论文解读(IDEC)《Improved Deep Embedded Clustering with Local Structure Preservation》

    Paper Information Title:<Improved Deep Embedded Clustering with Local Structure Preservation>A ...

  10. shell脚本命令

    http://man.linuxde.net/shell-script   从键盘或文件中获取标准输入:read命令 文件的描述符和重定向 数组.关联数组和别名的使用 函数的定义.执行.传参和递归函数 ...