using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization; namespace Utility
{
public class XMLHelper
{
#region object --> XML string.
public static string ToRequestXML<T>(T obj) where T : class
{
string xmlStr = string.Empty;
try
{
var type = typeof(T);
var properties = type.GetProperties();
XmlDocument xd = new XmlDocument();
XmlElement xe = xd.CreateElement("msgBody"); for (int i = ; i < properties.Length; i++)
{
var elementName = properties[i].Name; #region current type is List
if (properties[i].PropertyType.FullName.Contains("System.Collections.Generic.List"))
{
var propertyValue = properties[i].GetValue(obj, null);
if (propertyValue == null)
{
XmlElement xa = xd.CreateElement(elementName);
xe.AppendChild(xa);
}
else
{
xe = getArray(propertyValue, xe, xd, true, true, elementName);
}
continue;
}
#endregion #region current type is Array
if (properties[i].PropertyType.BaseType.Name == "Array")
{
var propertyName = properties[i].Name;
var propertyValue = properties[i].GetValue(obj, null);
if (propertyValue == null)
{
XmlElement xa = xd.CreateElement(elementName);
xe.AppendChild(xa);
}
else
{
xe = getArray(propertyValue, xe, xd, true, false, elementName);
}
continue;
}
#endregion #region current type is Model
if (properties[i].PropertyType.BaseType.Name != "Array" && (properties[i].PropertyType != typeof(long) && properties[i].PropertyType != typeof(int) && properties[i].PropertyType != typeof(string)) && !properties[i].PropertyType.FullName.Contains("System.Collections.Generic.List"))
{
var childPropertyName = properties[i].Name;
var childPropertyValue = properties[i].GetValue(obj, null); if (childPropertyValue == null)
{
var modelType = properties[i].PropertyType.UnderlyingSystemType;
var model = modelType.Assembly.CreateInstance(modelType.FullName);
xe = getArray(model, xe, xd, false, false, elementName);
}
else
{
xe = getArray(childPropertyValue, xe, xd, false, false, elementName);
}
continue;
}
#endregion #region current type is int or string
if (properties[i].PropertyType == typeof(long) || properties[i].PropertyType == typeof(string) || properties[i].PropertyType == typeof(int))
{
var childPropertyName = properties[i].Name;
var childPropertyValue = properties[i].GetValue(obj, null);
XmlElement xa = xd.CreateElement(childPropertyName);
if (childPropertyValue != null)
{
xa.InnerText = childPropertyValue.ToString();
}
else
{
xa.InnerText = "";
}
xe.AppendChild(xa);
continue;
}
#endregion
}
xd.AppendChild(xe);
xmlStr = xd.InnerXml;
return xmlStr;
}
catch (Exception ex)
{
throw ex;
}
}
#endregion #region Get array value
private static XmlElement getArray(object propertyValue, XmlElement xe, XmlDocument xd, bool isArray, bool isList , string elementName)
{
try
{
if (propertyValue != null)
{
if (isList)
{
#region current type is Array
var array = propertyValue as System.Collections.IEnumerable;
if (array != null)
{
foreach (var item in array)
{
var obj = item;
var type = item.GetType();
var properties = type.GetProperties();
XmlElement childXe = xd.CreateElement(elementName);
for (int i = ; i < properties.Length; i++)
{
var propertyType = properties[i].PropertyType; #region current type is List
if (properties[i].PropertyType.FullName.Contains("System.Collections.Generic.List"))
{
var elementName2 = properties[i].Name;
var propertyValue2 = properties[i].GetValue(obj, null);
if (propertyValue2 == null)
{
XmlElement xa = xd.CreateElement(elementName);
childXe.AppendChild(xa);
}
else
{
childXe = getArray(propertyValue2, childXe, xd, true, true, elementName2);
}
continue;
}
#endregion #region current type is Array
if (properties[i].PropertyType.BaseType.Name == "Array")
{
var elementName2 = properties[i].Name;
var childPropertyValue = properties[i].GetValue(obj, null);
if (childPropertyValue == null)
{
XmlElement xa = xd.CreateElement(elementName);
childXe.AppendChild(xa);
}
else
{
childXe = getArray(childPropertyValue, childXe, xd, true, false, elementName2);
} }
#endregion #region current type is Model
if (properties[i].PropertyType.BaseType.Name != "Array" && (properties[i].PropertyType != typeof(long) && properties[i].PropertyType != typeof(int) && properties[i].PropertyType != typeof(string)) && !properties[i].PropertyType.FullName.Contains("System.Collections.Generic.List"))
{
elementName = properties[i].Name;
var childPropertyValue = properties[i].GetValue(obj, null);
if (childPropertyValue == null)
{
var modelType = type.UnderlyingSystemType;
var model = modelType.Assembly.CreateInstance(modelType.FullName);
xe = getArray(model, xe, xd, false, false, elementName);
}
else
{
childXe = getArray(childPropertyValue, childXe, xd, false, false, elementName);
}
}
#endregion #region current type is Number
if (properties[i].PropertyType == typeof(long) || properties[i].PropertyType == typeof(string) || properties[i].PropertyType == typeof(int))
{
var childPropertyName = properties[i].Name;
var childPropertyValue = properties[i].GetValue(obj, null);
XmlElement xa = xd.CreateElement(childPropertyName);
if (childPropertyValue != null)
{
xa.InnerText = childPropertyValue.ToString();
}
else
{
xa.InnerText = "";
}
childXe.AppendChild(xa);
}
#endregion
}
xe.AppendChild(childXe);
}
}
else
{
var list = (List<object>)propertyValue;
}
#endregion
return xe;
} if (isArray)
{
#region current type is Array
var array = (Array)propertyValue;
if (array != null)
{
for (int i = ; i < array.Length; i++)
{
var obj = array.GetValue(i);
var type = array.GetValue(i).GetType();
var properties = type.GetProperties();
XmlElement childXe = xd.CreateElement(elementName);
for (int j = ; j < properties.Length; j++)
{
var propertyType = properties[j].PropertyType; #region current type is List
if (properties[j].PropertyType.FullName.Contains("System.Collections.Generic.List"))
{
var elementName2 = properties[j].Name;
var propertyValue2 = properties[j].GetValue(obj, null);
if (propertyValue2 == null)
{
XmlElement xa = xd.CreateElement(elementName);
childXe.AppendChild(xa);
}
else
{
childXe = getArray(propertyValue2, childXe, xd, true, true, elementName2);
}
continue;
}
#endregion #region current type is Array
if (properties[j].PropertyType.BaseType.Name == "Array")
{
var elementName2 = properties[j].Name;
var childPropertyValue = properties[j].GetValue(obj, null);
if (childPropertyValue == null)
{
XmlElement xa = xd.CreateElement(elementName);
childXe.AppendChild(xa);
}
else
{
childXe = getArray(childPropertyValue, childXe, xd, true, false, elementName2);
} }
#endregion #region current type is Model
if (properties[j].PropertyType.BaseType.Name != "Array" && (properties[j].PropertyType != typeof(long) && properties[j].PropertyType != typeof(int) && properties[j].PropertyType != typeof(string)))
{
elementName = properties[j].Name;
var childPropertyValue = properties[j].GetValue(obj, null);
if (childPropertyValue == null)
{
var modelType = properties[i].PropertyType.UnderlyingSystemType;
var model = modelType.Assembly.CreateInstance(modelType.FullName);
xe = getArray(model, xe, xd, false, false, elementName);
}
else
{
childXe = getArray(childPropertyValue, childXe, xd, false, false, elementName);
}
}
#endregion #region current type is Number
if (properties[j].PropertyType == typeof(long) || properties[j].PropertyType == typeof(string) || properties[j].PropertyType == typeof(int))
{
var childPropertyName = properties[j].Name;
var childPropertyValue = properties[j].GetValue(obj, null);
XmlElement xa = xd.CreateElement(childPropertyName);
if (childPropertyValue != null)
{
xa.InnerText = childPropertyValue.ToString();
}
else
{
xa.InnerText = "";
}
childXe.AppendChild(xa);
}
#endregion
}
xe.AppendChild(childXe);
}
}
else
{
var list = (List<object>)propertyValue;
}
#endregion
}
else
{
#region current type isn't Array
var objType = propertyValue.GetType();
var properties = objType.GetProperties();
XmlElement childXe = xd.CreateElement(elementName);
for (int j = ; j < properties.Length; j++)
{
var propertyType = properties[j].PropertyType; #region current type is Array
if (properties[j].PropertyType.BaseType.Name == "Array")
{
var elementName2 = properties[j].Name;
var childPropertyValue = properties[j].GetValue(propertyValue, null);
if (childPropertyValue == null)
{
XmlElement xa = xd.CreateElement(elementName);
childXe.AppendChild(xa);
}
else
{
childXe = getArray(childPropertyValue, childXe, xd, true, false, elementName2);
}
}
#endregion #region current type is Model
if (properties[j].PropertyType.BaseType.Name != "Array" && (properties[j].PropertyType != typeof(long) && properties[j].PropertyType != typeof(int) && properties[j].PropertyType != typeof(string)))
{
elementName = properties[j].Name;
var childPropertyValue = properties[j].GetValue(propertyValue, null);
if (childPropertyValue == null)
{
var modelType = properties[j].PropertyType.UnderlyingSystemType;
var model = modelType.Assembly.CreateInstance(modelType.FullName);
xe = getArray(model, xe, xd, false, false, elementName);
}
else
{
childXe = getArray(childPropertyValue, childXe, xd, false, false, elementName);
}
}
#endregion #region current is Number
if (properties[j].PropertyType == typeof(long) || properties[j].PropertyType == typeof(string) || properties[j].PropertyType == typeof(int))
{
var childPropertyName = properties[j].Name;
var childPropertyValue = properties[j].GetValue(propertyValue, null);
XmlElement xa = xd.CreateElement(childPropertyName);
if (childPropertyValue != null)
{
xa.InnerText = childPropertyValue.ToString();
}
else
{
xa.InnerText = "";
}
childXe.AppendChild(xa);
}
#endregion
}
xe.AppendChild(childXe);
#endregion
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
return xe;
}
#endregion #region XML string --> object
/// <summary>
/// Convert xml message to object
/// </summary>
/// <param name="type"></param>
/// <param name="xmlStr"></param>
/// <returns></returns>
public static T ToResponseObject<T>(string xmlStr) where T : new()
{
try
{
//T obj = default(T);
T obj = new T();
var repType = typeof(T);
XmlDocument document = new XmlDocument();
document.LoadXml(xmlStr); //加载Xml文件
XmlElement node = document.DocumentElement; //xml的根标签
var nodeList = document.ChildNodes;
var properties = repType.GetProperties(); foreach (var itemProp in properties)
{
#region current type is List
if (itemProp.PropertyType.FullName.Contains("System.Collections.Generic.List"))
{ object array = new object();
var arryLength = ;
var notNullLength = ;
var arryType = itemProp.PropertyType.UnderlyingSystemType; var objList = itemProp.GetValue(obj, null) as System.Collections.IEnumerable;
var enumt = objList.GetEnumerator();
//enumt.
var currentType = itemProp.PropertyType.GetGenericArguments()[]; foreach (XmlNode xmlitem in node.ChildNodes)
{
if (xmlitem.Name == itemProp.Name)
{
arryLength++;
}
}
if (arryLength > )
{
var arrayModel = arryType.InvokeMember("Set", System.Reflection.BindingFlags.CreateInstance, null, array, new object[] { arryLength }) as System.Collections.IList;
foreach (XmlNode item in node.ChildNodes)
{
//current type is array
if (item.Name == itemProp.Name)
{
var model = currentType.Assembly.CreateInstance(currentType.FullName); // arryType.GetElementType().Assembly.CreateInstance(currentType.FullName);
SetArray(item.ChildNodes, model,true);
arrayModel.Add(model);
//arrayModel[notNullLength] = model;
notNullLength++;
}
}
itemProp.SetValue(obj, arrayModel, null);
} continue;
}
#endregion var baseType = itemProp.PropertyType.BaseType.Name;
if (baseType == "Array")
{
#region Current type is Array
object array = new object();
var arryLength = ;
var notNullLength = ;
var arryType = itemProp.PropertyType.UnderlyingSystemType;
foreach (XmlNode xmlitem in node.ChildNodes)
{
if (xmlitem.Name == itemProp.Name)
{
arryLength++;
}
}
if (arryLength > )
{
var arrayModel = arryType.InvokeMember("Set", System.Reflection.BindingFlags.CreateInstance, null, array, new object[] { arryLength }) as System.Collections.IList;
foreach (XmlNode item in node.ChildNodes)
{
//current type is array
if (item.Name == itemProp.Name)
{
var model = arryType.GetElementType().Assembly.CreateInstance(arryType.GetElementType().FullName);
SetArray(item.ChildNodes, model);
arrayModel[notNullLength] = model;
notNullLength++;
}
}
itemProp.SetValue(obj, arrayModel, null);
}
#endregion continue;
}
else
{
#region Current type isn't Array
foreach (XmlNode item in node.ChildNodes)
{
#region Current type is Number
if (itemProp.Name == item.Name && (itemProp.PropertyType == typeof(long) || itemProp.PropertyType == typeof(int) || itemProp.PropertyType == typeof(string)))
{
if (itemProp.PropertyType == typeof(int) || itemProp.PropertyType == typeof(long))
{
if (!string.IsNullOrEmpty(item.InnerText))
{
if (itemProp.PropertyType == typeof(int))
{
itemProp.SetValue(obj, Convert.ToInt32(item.InnerText), null);
}
else
{
itemProp.SetValue(obj, Convert.ToInt64(item.InnerText), null);
} }
else
{
itemProp.SetValue(obj, , null);
}
}
else
{
itemProp.SetValue(obj, item.InnerText, null);
}
}
#endregion #region Current type is Model
if (itemProp.PropertyType != typeof(long) && itemProp.PropertyType != typeof(string) && itemProp.PropertyType != typeof(int) && itemProp.PropertyType.Name == item.Name && item.HasChildNodes && item.FirstChild.NodeType == System.Xml.XmlNodeType.Element)
{
var modelType = itemProp.PropertyType.UnderlyingSystemType;
var model = modelType.Assembly.CreateInstance(modelType.FullName);
SetArray(item.ChildNodes, model);
itemProp.SetValue(obj, model, null);
}
#endregion
}
#endregion continue;
}
}
repType = obj.GetType();
return obj;
}
catch (Exception ex)
{
throw ex;
}
}
#endregion #region Set array value
private static Object SetArray(XmlNodeList xmlNodeList, object obj,bool isList = false)
{
try
{
var type = obj.GetType();
var properties = type.GetProperties();
foreach (var itemProp in properties)
{
//if (isList)
if (itemProp.PropertyType.FullName.Contains("System.Collections.Generic.List"))
{
#region Current type is List
object array = new object();
var arryLength = ;
var notNullLength = ;
var arryType = itemProp.PropertyType.UnderlyingSystemType;
var currentType = itemProp.PropertyType.GetGenericArguments()[];
foreach (XmlNode xmlitem in xmlNodeList)
{
if (xmlitem.Name == itemProp.Name)
{
arryLength++;
}
} if (arryLength > )
{
var arrayModel = arryType.InvokeMember("Set", System.Reflection.BindingFlags.CreateInstance, null, array, new object[] { arryLength }) as System.Collections.IList;
foreach (XmlNode item in xmlNodeList)
{
//current type is array
if (item.Name == itemProp.Name)
{
var model = currentType.Assembly.CreateInstance(currentType.FullName); // var model = arryType.GetElementType().Assembly.CreateInstance(arryType.GetElementType().FullName);
SetArray(item.ChildNodes, model,true);
arrayModel.Add(model);
notNullLength++; }
}
itemProp.SetValue(obj, arrayModel, null);
}
#endregion
return obj;
} var baseType = itemProp.PropertyType.BaseType.Name;
if (baseType == "Array")
{
#region Current type is Array
object array = new object();
var arryLength = ;
var notNullLength = ;
var arryType = itemProp.PropertyType.UnderlyingSystemType;
foreach (XmlNode xmlitem in xmlNodeList)
{
if (xmlitem.Name == itemProp.Name)
{
arryLength++;
}
} if (arryLength > )
{
var arrayModel = arryType.InvokeMember("Set", System.Reflection.BindingFlags.CreateInstance, null, array, new object[] { arryLength }) as System.Collections.IList;
foreach (XmlNode item in xmlNodeList)
{
//current type is array
if (item.Name == itemProp.Name)
{
var model = arryType.GetElementType().Assembly.CreateInstance(arryType.GetElementType().FullName);
SetArray(item.ChildNodes, model);
arrayModel[notNullLength] = model;
notNullLength++; }
}
itemProp.SetValue(obj, arrayModel, null);
}
#endregion
}
else
{
foreach (XmlNode item in xmlNodeList)
{
#region Current type is Number
if (itemProp.Name == item.Name && (itemProp.PropertyType == typeof(long) || itemProp.PropertyType == typeof(int) || itemProp.PropertyType ==typeof(string)))
{
if (itemProp.PropertyType== typeof(int) || itemProp.PropertyType== typeof(long))
{
if (!string.IsNullOrEmpty(item.InnerText))
{
if (itemProp.PropertyType == typeof(int))
{
itemProp.SetValue(obj, Convert.ToInt32(item.InnerText), null);
}
else
{
itemProp.SetValue(obj, Convert.ToInt64(item.InnerText), null);
}
}
else
{
itemProp.SetValue(obj, , null);
}
}
else
{
itemProp.SetValue(obj, item.InnerText, null);
}
}
#endregion #region Current type is Model
if (itemProp.PropertyType != typeof(long) && itemProp.PropertyType != typeof(int) && itemProp.PropertyType != typeof(string) && itemProp.PropertyType.Name == item.Name && item.HasChildNodes && item.FirstChild.NodeType == System.Xml.XmlNodeType.Element)
{
var modelType = itemProp.PropertyType.UnderlyingSystemType;
var model = modelType.Assembly.CreateInstance(modelType.FullName);
SetArray(item.ChildNodes, model);
itemProp.SetValue(obj, model, null);
}
#endregion
}
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
return obj;
}
#endregion
} public class XMLNew
{
public static void ToXML()
{
try
{
TestA testA = new TestA();
List<TestC> testCList = new List<TestC>();
List<TestB> testBList = new List<TestB>();
List<TestD> testDList = new List<TestD>(); TestB testB = new TestB();
TestC testC = new TestC();
TestD testD = new TestD(); testCList.Add(testC);
testCList.Add(testC);
testBList.Add(testB);
testBList.Add(testB);
testDList.Add(testD);
testDList.Add(testD); testC.TestDArray = testDList.ToArray();
//testC.TestDList = testDList; //testB.TestCList = testCList;
testB.TestCArray = testCList.ToArray(); testA.TestBArray = testBList.ToArray();
//testA.TestBList = testBList; //string rqstXmlBody = Server.DataAccess.CallServerHelper.ToRequestXML<TestA>(testA);
string xml = Utility.XMLHelper.ToRequestXML<TestA>(testA); var obj = Utility.XMLHelper.ToResponseObject<TestA>(xml);
//var obj2 = Server.DataAccess.CallServerHelper.ToResponseObject<TestA>(rqstXmlBody);
}
catch (Exception ex)
{
//MessageHelper.Error(ex.Message);
}
}
} [Serializable]
public class TestD
{
public TestD()
{
D1 = "D1";
D2 = "D2";
}
public string D1 { get; set; }
public string D2 { get; set; }
} [Serializable]
public class TestC
{
public TestC()
{
C1 = "C1";
C2 = "C2";
}
public string C1 { get; set; }
public string C2 { get; set; } public TestD[] TestDArray { get; set; }
//public List<TestD> TestDList { get; set; }
} [Serializable]
public class TestB
{
public TestB()
{
//TestCList = new List<TestC>();
B1 = "B1";
B2 = "B2";
} public string B1 { get; set; }
public string B2 { get; set; } public TestC[] TestCArray { get; set; }
//public List<TestC> TestCList { get; set; }
} [Serializable]
public class TestA
{
public string A1 { get; set; }
public string A2 { get; set; }
public TestA()
{
//TestBList = new List<TestB>();
A1 = "A1";
A2 = "A2";
}
public TestB[] TestBArray { get; set; }
//public List<TestB> TestBList { get; set; }
} }

C#_XML与Object转换的更多相关文章

  1. 用于把List<Object>转换成Map<String,Object>形式

    /** * 用于把List<Object>转换成Map<String,Object>形式,便于存入缓存 * @author zhang_bo * @param keyName ...

  2. java Object转换成指定的类型

    java Object转换成指定的类型 /** * Object转成指定的类型 * @param obj * @param type * @param <T> * @return */ p ...

  3. LINQ系列:Linq to Object转换操作符

    转换是指将输入对象的类型转变为序列的动作. 1. AsEnumerable AsEnumerable操作符将查询的输入以IEnumberable(T)类型返回. 2. Cast Cast操作符将IEn ...

  4. C#如何把List of Object转换成List of T具体类型

    上周码程序的时候碰到个问题,因为设计上的约束,一个方法接受的参数只能为List<object>类型,然而该方法需要处理的真实数据则是确定的List<Currency>.然而C# ...

  5. 匿名类型和Object转换

    本文转载:http://www.cnblogs.com/JustRun1983/archive/2012/05/13/2497997.html net中的匿名类型非常好用, 但是开发中遇到一个问题,当 ...

  6. java中Object转换成int或String类型方法

    转载: http://www.cnblogs.com/1020182600HENG/p/6137206.html Object obj = getObject(); if(obj instanceof ...

  7. 将Object转换成Dictionary方法

    如果Object是Dictionary类型,直接返回 如果Object是NameValueCollection类型,则添加到Dictionary里 如果Object是Hashtable类型,添加到Di ...

  8. 将[object Object]转换成json对象

    这两天在做中英文双版的文件,页面根据语言读取不同的内容.js模板用的是ejs json文件: "components":{ "pages":{ "ho ...

  9. 将object转换成dyamic类型 解决long输出到浏览器过长精度丢失问题

    需求: 数据库使用飘雪算法保存唯一标识  是一个18位长整形 将数据输出到浏览器时出现了精度丢失问题,这是一个重大的BUG.如果没解决好整个项目都要改一遍. 讨论有三个办法 1.把所有实体 数据模型的 ...

随机推荐

  1. django学习之命令

    1.启动一个django项目: $ django-admin startproject <project-name> 2.创建一个应用: $ python manage.py starta ...

  2. 洗礼灵魂,修炼python(59)--爬虫篇—httplib模块

    httplib 1.简介 同样的,httplib默认存在于python2,python3不存在: httplib是python中http协议的客户端实现,可以用来与 HTTP 服务器进行交互,支持HT ...

  3. python第一百零五天 ---Django 基础 路由系统 URL 模板语言 ORM 操作

    一 路由系统 URL 1 url(r'^index/',views.index) url(r'^home/', views.Home.as_view()) 2 url(r'^detail-(\d+). ...

  4. 【PAT】B1080 MOOC期终成绩(25 分)

    还是c++好用,三部分输入直接用相同的方法, 用map映射保存学生在结构体数组中的下标. 结构体保存学生信息,其中期末成绩直接初始化为-1, 注意四舍五入 此题还算简单 #include<ios ...

  5. ccf-20161203--权限查询

    这题我的思路是将用户直接与他的权限联系起来.比如: 用户 角色 权限 Alice hr crm:2直接转变为:Alice: crm:2 题目与代码如下: 问题描述 试题编号: 201612-3 试题名 ...

  6. elasticsearch使用bulk实现批量操作

    本篇文章提供ES原生批量操作语法及使用bulk批量操作文档.文章依旧提供语法,具体实现大家根据语法,在对应处进行替换即可 一.原生批量获取文档 1.获取指定文档值(1) 语法: GET /_mget ...

  7. SAP UI 搜索分页技术

    搜索分页技术往往和另一个术语Lazy Loading(懒加载)联系起来.今天由Jerry首先介绍S/4HANA,CRM Fiori和S4CRM应用里的UI搜索分页的实现原理.后半部分由SAP成都研究院 ...

  8. pb数据窗口之间的传参

    问题描述: 通过一个窗口打开一个子窗口并传递指定参数查询详细信息 解决方法: 在前者窗体的user object下的itemchanged事件中,相应位置加入openwithparm函数 :   op ...

  9. phpize安装php扩展CURL

    进入php源码包curl扩展目录 cd php-/ext/curl phpize ./configure --with-php-config=/usr/local/webserver/php/bin/ ...

  10. python之面向对象进阶

    接口类 抽象类 钻石继承 多态 鸭子类型 接口类 接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface, ...