精华内容
下载资源
问答
  • 比如一个父类对象是户主,对应的多个子类对象是户主的物业缴费账单。假如用继承的话,那每创建一个账单对象就都要创建一个新的户主对象。我在想怎么让一个户主对象可以对应多个账单对象。
  • 整理一下理解的几种模式的的实例化: Singleton:单态,这个只能被实例化一次 Factory Method:在...Abstract Factory:在Factory子类里,进行,多个“product子类”的实例化,一个是product1子类

           整理一下理解的几种模式的类的实例化:

    Singleton:单态,这个类只能被实例化一次

    Factory Method:在Factory子类里,进行,product类的子类的实例化(Simple Factory看为Factory Method模式的一种特例)

    Abstract Factory:在Factory子类里,进行,多个“product类的子类”的实例化,一个是product1类的子类,一个是product2类的子类......而且这两个子类是存在关系的

           (他们的区别参考:Factory Method模式与Abstract Factory模式区别12)

           Simple Factory动态实例化一个类,Factory Method和Abstract Factory动态实例化一个类的子类,log4**系列代码有这样的例子,也许他们考虑到还要做完全不同类型的工厂类的管理

    1.     log4cplus中Simple Factory和Factory Method的实现方式

           product类:

    class  Logger----

    class Appender----

        class ConsoleAppender : public Appender

        class FileAppender : public Appender

        class RollingFileAppender : publicFileAppender

     

           Factory类:

    class  LoggerFactory----

    classAppenderFactory : public BaseFactory----

        class ConsoleAppenderFactory : publicAppenderFactory

        class FileAppenderFactory : publicAppenderFactory

        class RollingFileAppenderFactory : publicAppenderFactory  

    (

    class LayoutFactory: public BaseFactory----

        class SimpleLayoutFactory : publicLayoutFactory

        class TTCCLayoutFactory : publicLayoutFactory

        class PatternLayoutFactory : publicLayoutFactory

    )

           (1)Logger是通过Simple Factory来实现的,LoggerFactory工厂就是实例化一个Logger类
           (2)Appender和Layout是通过Factory Method来实现的,这里AppenderFactory和LayoutFactory就是工厂方法的基工厂类(撇开BaseFactory不谈,对工厂方法而言),ConsoleAppenderFactory子工厂类中做的工作就实例化ConsoleAppender类

           (3)Logger是巧妙的通过
    typedef std::map<log4cplus::tstring, Logger> LoggerMap;
           来管理logger_name和Logger实例的 
           (4)Appender类和Layout类很巧妙的新建了一个类AppenderFactoryRegistry和LayoutFactoryRegistry来实现的,主要是考虑到和AppenderFactory平行的LayoutFactory还可以扩展其他的工厂类

           AppenderFactoryRegistry和LayoutFactoryRegistry作用也是利用std::map来管理appender_name和Appender实例

           不管是LoggerFactory还是AppenderFactory,都是通过Factory去维护一个对象名称到对象实例的一个映射关系

    2.     log4j中采用的JAVA反射机制

           在log4j中上面两种模式JAVA很简单的采用反射机制就可以实现,JAVA反射机制如下:
           在运行时,判断任意一个对象所属的类
           在运行时,调用任意一个对象的方法
           在运行时,判断任意一个类所具有的成员变量和方法
           在运行时,构造任意一个类的对象(Class.forName(), newInstance())       

           instantiateByClassName是在通过反射实例化对象的时候调用,而findAndSubst是在解析配置文件时,判断是否存在指定键值的。 
    //
           已经存在category_factory,可以直接用instantiateByClassName
    protected void configureCategoryFactory(Properties props) {
    String factoryClassName = OptionConverter.findAndSubst(CATEGORY_FACTORY_KEY,
      props);    
    if(factoryClassName != null) {
      LogLog.debug("Setting category factory to ["+factoryClassName+"].");
      categoryFactory = (CategoryFactory) 
                  OptionConverter.instantiateByClassName(factoryClassName,
    CategoryFactory.class, 
    categoryFactory);
      PropertySetter.setProperties(categoryFactory, props, FACTORY_PREFIX + ".");
    }
    }
    ///
    public
    static
    Object instantiateByClassName(String className, Class superClass,
    Object defaultValue) {
    if(className != null) {
      try {
    Class classObj = Class.forName(className);
    if(!superClass.isAssignableFrom(classObj)) {
      LogLog.error("A \""+className+"\" object is not assignable to a \""+
          superClass.getName() + "\" variable.");
      return defaultValue;  
    }
    return classObj.newInstance();
      }
      catch (Exception e) {
    LogLog.error("Could not instantiate class [" + className + "].", e);
      }
    }
    return defaultValue;    
    }
    //
           相当于appender_factory的功能
      Appender parseAppender(Properties props, String appenderName) {
        Appender appender = registryGet(appenderName);
        if((appender != null)) {
          LogLog.debug("Appender \"" + appenderName + "\" was already parsed.");
          return appender;
        }
        // Appender was not previously initialized.
        String prefix = APPENDER_PREFIX + appenderName;
        String layoutPrefix = prefix + ".layout";    


        appender = (Appender) OptionConverter.instantiateByKey(props, prefix,
         org.apache.log4j.Appender.class,
         null);
    ......
    Layout layout = (Layout) OptionConverter.instantiateByKey(props, 
     layoutPrefix,
     Layout.class, 
     null);      
    ///     
    public
    static
    Object instantiateByKey(Properties props, String key, Class superClass,
    Object defaultValue) {


    // Get the value of the property in string form
    String className = findAndSubst(key, props);
    if(className == null) {
      LogLog.error("Could not find value for key " + key);
      return defaultValue;
    }
    // Trim className to avoid trailing spaces that cause problems.
    return OptionConverter.instantiateByClassName(className.trim(), superClass,
     defaultValue);
    }
    //  

           下面google到的两个个例子(12)是一种完全不同的处理方式,也是一个写C++的同学推荐的方法

           简单工厂类维护一个对象名称到对象实例的映射

           工厂方法基类里面有个静态createInstance函数,然后每个子类继承这个createInstance函数,每个子类的createInstance自己实例化自己一个实例,在外面函数调用基类的createInstance,非常简单就实例化一个子类

    3.     简单工厂维护name到实例的映射 

    {

        // store instances of pools   
        private static Map<String,SockIOPool> pools =   
            new HashMap<String,SockIOPool>();   
      
      
      
        // empty constructor   
        protected SockIOPool() { }   
      
      
        /**    
         * Factory to create/retrieve new pools given a unique poolName.    
         *    
         * @param poolName unique name of the pool   
         * @return instance of SockIOPool   
         */   
        public static synchronized SockIOPool getInstance( String poolName ) {   
            if ( pools.containsKey( poolName ) )   
                return pools.get( poolName );   
      
            SockIOPool pool = new SockIOPool();   
            pools.put( poolName, pool );   
      
            return pool;   
        }   
      
        /**    
         * Single argument version of factory used for back compat.   
         * Simply creates a pool named "default".    
         *    
         * @return instance of SockIOPool   
         */   
        public static SockIOPool getInstance() {   
            return getInstance( "default" );   
        }  
    }    
     

    4.     工厂方法模式的智能化实现

    #include<iostream>

    #include <map>

    #include<string>

     

    class Shape;

     

    typedef Shape*(*FactoryFunction)();

     

    class ShapeFactory

    {

    public:

           static void Register(std::string name,FactoryFunction instanceFunction)

                  {m_FactoryFunctions[name] =instanceFunction;};

           static Shape * getInstance(std::stringname)

                  { if(m_FactoryFunctions.count(name))                     returnm_FactoryFunctions[name]();

                   else       return NULL; }

    private:

           staticstd::map<std::string,FactoryFunction> m_FactoryFunctions;

    };

     

    std::map<std::string,FactoryFunction>ShapeFactory::m_FactoryFunctions;

     

    class Shape

    {

    public:

           virtual void  Draw() = 0;

    };

     

    class Circle :public Shape

    {

    public:

           void Draw()  { std::cout << "Drawing aCircle......Done" << std::endl; }

           static Shape *createInstance() {returnnew Circle;}

    };

     

    class Triangle :public Shape

    {

    public:

           void Draw()  { std::cout << "Drawing aTriagnle......Done" << std::endl; }

           static Shape *createInstance() {returnnew Triangle;}

    };

     

    int main()

    {

          ShapeFactory::Register("circle",   &  Circle::createInstance);

          ShapeFactory::Register("Triangle", &Triangle::createInstance);

     

           Shape * pShape = NULL;

     

           pShape =ShapeFactory::getInstance("circle");

           if (NULL == pShape)

           {

                  std::cout << "can'tfind the product in the factory" << std::endl;

                  delete pShape;

           }

           else

           {

                  pShape->Draw();

                  delete pShape;

           }

           return 0;

    }


    展开全文
  • 多继承与接口的核心区别: 多继续:子类包含所欲父类的所有方法。 接口:子类(实现)只包含多个接口的1个方法!!

    多继承与接口的核心区别:   多继续:子类包含所欲父类的所有方法。 接口:子类(实现类)只包含了多个接口中的1个方法!!

    展开全文
  • //一个子类可以同时继承抽象和实现接口 //接口 interface A{ public static final String FLAG="天河学院"; public abstract void print(); public abstract String getInfo(); } //抽象 ...
    package study;
    //一个子类可以同时继承抽象类和实现接口
    
    
    //接口
    interface A{
    	public static final String FLAG="天河学院";
    	public abstract void print();
    	public abstract String getInfo();
    }
    
    //抽象类
    abstract class B{
    	public abstract void fun();
    }
    
    
    //普通类,先继承抽象类在实现接口
    class C extends B implements A{
    	public void print() {
    		System.out.println(FLAG);	
    	}
    	public String getInfo() {
    		return "继承抽象类再实现接口";
    	}
    	public void fun() {
    		System.out.println("接口包含全局常量和抽象方法");
    	}
    }
    
    
    public class exercise {
    	public static void main(String[] args) {
    		C c=new C();
    		c.print();
    		c.fun();
    		System.out.println(c.getInfo());
    	}
    }
    
    
    展开全文
  • 而抽象在代码实现方面发挥作用,可以实现代码的重用,例如,模板方法设计模式是抽象一个典型应用,假设某个项目的所有Servlet都要用相同的方式进行权限判断、记录访问日志和处理异常,那么就可以定义一个...

    接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代码,伪代码如下:

    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    public abstract class BaseServlet extends HttpServlet {
        public final void service(HttpServletRequest request, HttpServletResponse response)
                throws IOException, ServletException {
            // 记录访问日志
            // 进行权限判断
        }

        protected abstract void doService(HttpServletRequest request, HttpServletResponse response)
                throws IOException, ServletException;
            // 注意访问权限定义成protected,显得既专业,又严谨,因为它是专门给子类用的
    }

    class MyServlet1 extends BaseServlet {
        protected void doService(HttpServletRequest request, HttpServletResponse response)
                throws IOException, ServletException {
            // 本Servlet只处理的具体业务逻辑代码
        }
    }

    父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式。

    备注:这道题的思路是先从总体解释抽象类和接口的基本概念,然后再比较两者的语法细节,最后再说两者的应用区别。比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法(包括抽象方法),静态变量和方法,继承性等6个方面逐一去比较回答,接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功底。

    展开全文
  • python的子类

    千次阅读 2019-04-23 11:56:54
    python也提供了一种方法将代码及其处理的数据定义为一个类,一旦有了,就可以用它来创建(或实例化)数据对象,它会继承的特性; 在面向对象的世界里,代码通常称为的方法method,而数据通常称为的属性...
  • 设计一个形状Shape,方法:求周长和求面积形状子类:Rect(矩形),Circle(圆形)Rect子类:Square(正方形)不同的子类会有不同的计算周长和面积的方法创建三个不同的形状对象,放在Shape类型的数组里,分别打印出每...
  • View及其子类

    千次阅读 2019-11-26 19:37:32
    View及其子类 View(视图) View位于android.view包中; View子类一般位于android.widget包中。 View常用的属性 **1. android:id 属性** 例:android:id="@+id/user" user为id值 **2. android:...
  • Java基础篇——子类

    千次阅读 2020-06-04 19:52:28
    1. 什么是,什么是子类是Java程序的基本要素,一个Java应用程序...简单理解:在生活也是无处不在的,比如说所有的动物就是一个类,叫动物,他们能吃东西,能跑等等。当然在动物存在长颈鹿、狮子
  • 定义一个派生对象(子类) 1、构建所包含的基类(父类)对象:由基类的构造函数完成 2、构建所包含的成员对象:由成员对象的构造函数完成 3、构建派生对象:由派生的构造函数完成 注意:基类对象和成员对象...
  • 写代码过程想要将装有不同子类的很多容器都传参到一个 函数(包含一个装有父类容器的形参)做一些基本操作,想 通过这样的方式减少重复写多个相似函数 还是说我这样必须通过模板实现,可以给一些提示么
  • JAVA父类,子类,内部

    万次阅读 2012-10-11 17:58:40
    一个.java源文件可以有多个类(不包含内部),但是只有一个类是Public的,如 public class Test {  public class A{//内部  }  public class B{//内部  } // /** // * @param args // */  ...
  • 个子类一个表; 每个具体内一个表(有限制)。 假设我们有四个Animal,Dog,Cat,其代码如下: 文件名:Animal.javaclass Animal {  private String identifier;  private String name;...
  • 、超类和子类

    千次阅读 2019-10-28 21:06:55
    is-a 关系是继承的一个明显特征。 extends是派生关键字,被继承的被称为超类-superclass,基类-base class 或者父类parent class。 派生出来的,被称为子类 subclass、派生-derived class或者孩子-child ...
  • 如何获取某个的所有子类

    千次阅读 2019-11-14 09:46:16
    如何获取某个的所有子类引言解决方案(获取基础与IAnimal的所有...举个例子,我们定义了很动物(Animal),我们需要一个AnimalFactory根据动物类型(type)去构建不同的动物实例。如下代码所示: 我们先构建一个动...
  • 如果子类中的成员变量和父类的重名,就用域作用符,父类名::变量名,来对父类的同名成员变量进行访问。 多态:为了能够对不同的继承类型,调用其下作用不同的同名函数,因此引入了多态的概念。 根据(父类)...
  • (Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合对象所共有的属性和方法。... 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这过程叫方法的覆盖(ove...
  • Java 子类与继承关于abstract和abstract方法的理解 .abstract 声明 用关键字abstract修饰的叫做abstract(抽象) public abstract class A { … } 二.abstract方法 用关键字abstract修饰的方法叫做...
  • *建立一个超类House, 和一个子类Home,并提供一系列属性和方法,包括printDetails方法, 这个方法要采用态性 *建立一个House和Home的异类集合, 测试printDetails方法的态性
  • 在一期财务项目,一个子类业务对象和父类业务对象同时注入同一个属性时,如果子类调用父类一个方法,如果该父类的方法引用了之前注入的属性,该属性是被子覆盖的,也就是说在父类的上下文中,该属性是空的,...
  • 假设声明两个类A和B,如果需要在A.h定义B对象,B b_; 势必要包含# include “B.h”,而B类中需要定义A对象A a_; 也要包含B.h,但是相互包含是不允许的,称为环形引用,这时候就用到了前向声明 文章目录1,a.h ...
  • C++实例以及子类在内存的分配

    千次阅读 2013-10-19 00:34:04
    关于结构体和C++的内存地址问题 今天终于有时间写点 东西了~ 太爽了 *_* 很多人都知道C++是由结构体发展得来的,所以他们... 一个类对象的地址就是包含的这一片内存空间的首地址,这个首地址也就对应具体
  • 利用多态特性,创建一个手机Phones,定义打电话的方式call,创建三个子类,并在各自的方法重写方法,编写程序入口main()方法,实现两种手机打电话 |--解题思路 采用简单工厂模式, 设计四个角色: 工厂、...
  • 但是想要看一个类或者接口的所有子类或实现的话,网上并没有一个特别好的教程可以参考(也许是我没有找到)。基于这个原因,我就过一番研究(其实就是到处乱点)找到了对应的方法。于是写出来与大家分享,如有雷同...
  • 写在前面的话(就先听听) ... 然后子类又继承了一个孙子,孙子有添加了若干个成员,然后定义了什么函数虚函数之的,请问孙子的内存大小又是多少呢? 然后就一直摸棱两可的回答了一通,...
  • 1、首先有一个接口,包含了三个实现。 2、三个实现分别重写其中一个方法。 3、依赖注入时,全部注入到父接口,通过Map方式接收 其中map的key就是实现的类名,value就是依赖注入的 4、具体...
  • class的继承和子类(二) python

    千次阅读 2013-11-21 16:37:00
    定义一个类的时候,可以在类名后面紧跟一对括号,在括号指定所继承的父类,如果有多个父类,多个父类名之间用逗号隔开。 它们从父类那里继承了属性和方法。如果一个方法在子类的实例被调用,或者一个属性在...
  • 第7.19节 Python的抽象详解:abstractmethod、abc与真实子类 、 引言 前面相关的章节已经介绍过,Python定义某种类型是以实现了该类型对应的协议为标准的,而不是以继承关系为标准,在各种调用,不会显式...
  • 其中有反射的一个坑,工具某方法反射获取传入Model的属性值.但是当我把公共属性抽出来做基类的时候,发现获取不到基类的属性值了.原因是使用了getDeclaredFields(); 分析 方法 功能 getFields() ...
  • 快速查看子接口或实现的...然而在 IDEA 里阅读源码也需要一些技巧,才能如上图所示比较方便地看到一个类或接口的上下层关系。现将其记录如下: 一、将光标放至/接口签名上,然后按 ctrl+H 这个方法可以不仅可以看

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 483,103
精华内容 193,241
关键字:

一个类中包含多个子类