子类获得父类的值[转]

利用java反射机制,子类从父类拷贝属性--解决信息修改类设计的模式


用例场景:在一个商户管理系统中,操作人员对一个已注册的商户进行修改,这就触发了一个商户修改的工作流,修改提交后,修改的商户信息和原商户信息会传递到审核人员的窗口进行审核,审核完毕后,新商户信息更新,同时旧商户信息去到历史库。



数据库:我们这里有三张表——BusiInfo,BusiInfo_hist,BusiInfo_ba。BusiInfo是商户信息表存放经过注册的商户信息;BusiInfo_hist是商户信息历史表,将修改完成后的商户原信息保存到此处;BusiInfo_ba是商户信息在途表,保存并未审核通过的修改后信息,当审核通过后转移到_hist历史表,并将在途信息删除。



例子:比如商户信息为a,现在修改为b,我们看看各表中的数据如何变化。
修改前 修改中 修改后
BusiInfo a a b
BusiInfo_ba b
BusiInfo_hist a





好,现在我们开始编码,我们采用的是hibernate,通常的做法是每个表对应一个javabean,当信息在不同表中进行转移的时候,通常的做法是将先一个javabean中的信息一个一个getMessage(),然后再一个一个setMessage()到另一个javabean中。如果属性很多的话这是一个体力活,同时如果以后有新增属性的话,还要回来维护这个传值的方法。



我们决定找到一个一劳永逸的方法来解决这类问题。这里我们用到了java继承和反射机制。
Java代码 收藏代码

package com.mytesta;
/**
* 商户信息类,父类
*/
public class BusiInfoIn {
public String busiId;
public String busiLoginname;
public Long number;
public Long getNumber() {
return number;
}
public void setNumber(Long number) {
this.number = number;
}
public String getBusiId() {
return busiId;
}
public void setBusiId(String busiId) {
this.busiId = busiId;
}
public String getBusiLoginname() {
return busiLoginname;
}
public void setBusiLoginname(String busiLoginname) {
this.busiLoginname = busiLoginname;
}
}

Java代码 收藏代码

package com.mytesta;
/**
* 商户历史信息类,子类,同理可建立商户在途信息类
*
*/
public class BusiInfoIn_his extends BusiInfoIn {
public String deleteDate;

public String getDeleteDate() {
return deleteDate;
}

public void setDeleteDate(String deleteDate) {
this.deleteDate = deleteDate;
}
}


Java代码 收藏代码

package com.mytesta;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import junit.framework.TestCase;

public class BusiInfoTest extends TestCase {
public void test() throws Exception {
//
BusiInfoIn_his busiInfoIn_his=new BusiInfoIn_his();
busiInfoIn_his.setBusiId("1243124");
busiInfoIn_his.setBusiLoginname("jeffen");
busiInfoIn_his.setDeleteDate("2009-1-1");
BusiInfoIn busiInfo =new BusiInfoIn();
busiInfo=(BusiInfoIn)busiInfoIn_his;
System.out.println("子类传父类=============================");
System.out.println(busiInfo.getBusiId());
System.out.println(busiInfo.getBusiLoginname());

BusiInfoIn busiInfo2 =new BusiInfoIn();
busiInfo2.setBusiId("09090909");
busiInfo2.setBusiLoginname("runrun");
busiInfo2.setNumber(11L);
BusiInfoIn_his busiInfoIn_his2=new BusiInfoIn_his();
this.fatherToChild(busiInfo2, busiInfoIn_his2);
System.out.println("父类传子类=============================");
System.out.println(busiInfoIn_his2.getBusiId());
System.out.println(busiInfoIn_his2.getBusiLoginname());
System.out.println(busiInfoIn_his2.getNumber());
System.out.println(busiInfoIn_his2.getDeleteDate());


}
/*
* 将父类所有的属性COPY到子类中。
* 类定义中child一定要extends father;
* 而且child和father一定为严格javabean写法,属性为deleteDate,方法为getDeleteDate
*/
private void fatherToChild (Object father,Object child)throws Exception{
if(!(child.getClass().getSuperclass()==father.getClass())){
throw new Exception("child不是father的子类");
}
Class fatherClass= father.getClass();
Field ff[]= fatherClass.getDeclaredFields();
for(int i=0;i<ff.length;i++){
Field f=ff[i];//取出每一个属性,如deleteDate
Class type=f.getType();
Method m=fatherClass.getMethod("get"+upperHeadChar(f.getName()));//方法getDeleteDate
Object obj=m.invoke(father);//取出属性值
f.set(child,obj);
}
}
/**
* 首字母大写,in:deleteDate,out:DeleteDate
*/
private String upperHeadChar(String in){
String head=in.substring(0,1);
String out=head.toUpperCase()+in.substring(1,in.length());
return out;
}

}

我们可以看到子类比父类多了一个属性deleteDate,代表进入历史表的时间。上面的运行结果如下
Java代码 收藏代码

子类传父类=============================
1243124
jeffen
父类传子类=============================
09090909
runrun
11
null

可以看到只要我们的持久类采用标准的javabean格式,子类从父类拷贝属性信息一步完成,而且不受以后属性增减的影响。

子类继承父类是面向对象编程中的重要概念,以下从原理、实现方法和使用场景三个方面进行阐述。 ### 原理 在类的继承机制里,子类获得父类的属性和方法。这意味着子类可以复用父类的代码,避免重复编写。当子类继承父类时,它会继承父类的所有非私有成员(包括属性和方法),这些成员成为子类的一部分,就好像是子类自己定义的一样。不过,父类构造方法中的初始通常无法直接被继承,这时候可以在子类中使用特定方法(如 Python 里的 `super` 函数)来调用父类方法,特别是在多重继承的情况下 [^1]。 ### 实现方法 不同编程语言实现子类继承父类的语法有所不同: - **Python**:使用 `class` 关键字定义子类,在类名后加上父类名,并用括号括起来。如需调用父类方法,可使用 `super()` 函数。示例如下: ```python class Parent: def __init__(self): print("Parent constructor") def parent_method(self): print("This is a parent method") class Child(Parent): def __init__(self): super().__init__() # 调用父类的构造方法 print("Child constructor") def child_method(self): print("This is a child method") child = Child() child.parent_method() child.child_method() ``` - **C++**:在定义子类时,在类名后使用 `:` 符号,然后指定继承方式(如 `public`、`private`、`protected`)和父类名。示例如下: ```cpp #include <iostream> class Parent { public: Parent() { std::cout << "Parent constructor" << std::endl; } void parentMethod() { std::cout << "This is a parent method" << std::endl; } }; class Child : public Parent { public: Child() { std::cout << "Child constructor" << std::endl; } void childMethod() { std::cout << "This is a child method" << std::endl; } }; int main() { Child child; child.parentMethod(); child.childMethod(); return 0; } ``` - **Java**:使用 `extends` 关键字来实现继承。示例如下: ```java class Parent { public Parent() { System.out.println("Parent constructor"); } public void parentMethod() { System.out.println("This is a parent method"); } } class Child extends Parent { public Child() { super(); // 调用父类的构造方法 System.out.println("Child constructor"); } public void childMethod() { System.out.println("This is a child method"); } public static void main(String[] args) { Child child = new Child(); child.parentMethod(); child.childMethod(); } } ``` ### 使用场景 子类继承父类在以下场景中非常有用: - **代码复用**:当多个类具有一些共同的属性和方法时,可以将这些共同部分提取到一个父类中,然后让其他类继承该父类,从而避免代码重复。例如,在一个图形绘制系统中,圆形、矩形、三角形等图形都有一些共同的属性(如颜色、位置)和方法(如绘制、移动),可以创建一个 `Shape` 父类,让其他图形类继承它。 - **扩展功能**:在不修改父类代码的前提下,子类可以添加新的属性和方法,或者重写父类方法来实现特定的功能。比如,在一个游戏中,父类 `Character` 定义了角色的基本属性和行为,子类 `Warrior` 可以继承 `Character` 并添加一些特殊技能。 - **实现多态**:多态允许不同的子类对象对同一消息做出不同的响应。通过继承和方法重写,可以实现多态性,提高代码的灵活性和可扩展性。例如,在一个动物类层次结构中,父类 `Animal` 有一个 `makeSound` 方法子类 `Dog` 和 `Cat` 可以重写该方法,分别发出不同的声音。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值