数组的静态继承

时间:2015-07-29 09:05:08

标签: php oop inheritance

我很难解释我想要做什么,所以我只是提供一个例子

class A {
    static $data = ['a'];

    static function getData() { return static::$data; }
}

class B extends A {
    static $data = ['b'];
}

class C extends B {
    static $data = ['c'];
}

class D extends B {
    static $data = ['d'];
}

$a = new A;
$b = new B;
$c = new C;
$d = new D;

$a::getData(); // Output: Array('a'), Expected: Array('a');
$b::getData(); // Output: Array('b'), Expected: Array('a', 'b');
$c::getData(); // Output: Array('c'), Expected: Array('a', 'b', 'c');
$c::getData(); // Output: Array('d'), Expected: Array('a', 'b', 'd');

这有可能吗?

编辑:我有我的数据对象,每个对象都有一套属性规则。例如,一个User对象有一个属性name,最多可以有10个符号,我在用户类的规则中定义它,然后所有用户对象在其属性name即将到来时将遵守该规则改变。 rules数组是静态的,因为它们适用于此类的所有对象。但是,当我在VIP用户中继承它时,VIP将需要具有基本用户没有的属性的附加规则。我需要能够扩展规则数组,但是如果我在子类中定义这样的数组,它只会覆盖我也需要的父规则。

3 个答案:

答案 0 :(得分:2)

这将实现你想要的目标

String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Cursor address_cursror = getContentResolver().query(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI, null, ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + " = ?", new String[] { id }, null);
                while (address_cursror.moveToNext())
                {

                    String name = address_cursror.getString(address_cursror.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.DISPLAY_NAME));
                    String street = address_cursror.getString(address_cursror.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));
                    String state = address_cursror.getString(address_cursror.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
                    String zip = address_cursror.getString(address_cursror.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE));
                    String city = address_cursror.getString(address_cursror.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
            }

            } while (cursor.moveToNext());

Demo

虽然可能只是在A类中定义getData()的方式稍微更清晰一些

答案 1 :(得分:2)

您想要合并数组,但在您的示例代码中,您永远不会指定它。对[ERROR ] /Users/915655/Documents/Projects/R2O/New%20Workspace/MobileFirstServerConfig/servers/worklight/workarea/org.eclipse.osgi/bundles/73/data/cache/com.ibm.ws.app.manager_93/.cache/WEB-INF/lib/ibm_web20_wink_no_abdera_no_jackson-1.1.0.0-20110422.jar (No such file or directory) /Users/915655/Documents/Projects/R2O/New%20Workspace/MobileFirstServerConfig/servers/worklight/workarea/org.eclipse.osgi/bundles/73/data/cache/com.ibm.ws.app.manager_93/.cache/WEB-INF/lib/ibm_web20_wink_no_abdera_no_jackson-1.1.0.0-20110422.jar (No such file or directory) [ERROR ] /Users/915655/Documents/Projects/R2O/New%20Workspace/MobileFirstServerConfig/servers/worklight/workarea/org.eclipse.osgi/bundles/73/data/cache/com.ibm.ws.app.manager_93/.cache/WEB-INF/lib/ibm_web20_wink_no_abdera_no_jackson-1.1.0.0-20110422.jar (No such file or directory) /Users/915655/Documents/Projects/R2O/New%20Workspace/MobileFirstServerConfig/servers/worklight/workarea/org.eclipse.osgi/bundles/73/data/cache/com.ibm.ws.app.manager_93/.cache/WEB-INF/lib/ibm_web20_wink_no_abdera_no_jackson-1.1.0.0-20110422.jar (No such file or directory) [ERROR ] Uncaught.init.exception.thrown.by.servlet ManagementServlet WorklightServices java.lang.NoClassDefFoundError: Could not initialize class org.apache.wink.common.internal.i18n.Messages at org.apache.wink.server.internal.DeploymentConfiguration.initAlternateShortcutMap(DeploymentConfiguration.java:386) at org.apache.wink.server.internal.DeploymentConfiguration.init(DeploymentConfiguration.java:167) at org.apache.wink.server.internal.servlet.RestServlet.getDeploymentConfiguration(RestServlet.java:202) at org.apache.wink.server.internal.servlet.RestServlet.createRequestProcessor(RestServlet.java:138) at org.apache.wink.server.internal.servlet.RestServlet.init(RestServlet.java:103) at javax.servlet.GenericServlet.init(GenericServlet.java:161) at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:325) at [internal classes] at com.ibm.worklight.admin.common.filter.HSTSFilter.doFilter(HSTSFilter.java:110) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:194) at [internal classes] 的调用获取父类,如果不存在则调用为false。

此外,您无法使用get_parent_class(get_called_class()),但如果要使用已调用的实际类的值,则必须使用selfstatic将始终使用相同的值。

self

答案 2 :(得分:2)

所以是的,只有父类方法可以做到这一点:

class A
{
    public static $data = ['a'];

    public static function getData()
    {
        $result = static::$data;
        $class  = get_called_class();
        while ($class = get_parent_class($class)) {
            $result = array_merge($result, $class::$data);
        }

        return $result;  
    }
}

class B extends A 
{
    public static $data = ['b']; 
}

class C extends B 
{
    public static $data = ['c']; 
}

class D extends C 
{
    public static $data = ['d']; 
}

演示here

如果订单很重要,那么更改合并参数顺序(现在它就像它在类层次结构链中一样 - 从子级到父级)

或者,使用class_parents()

class A
{
    public static $data = ['a'];

    public static function getData()
    {
        $classes  = [get_called_class()]; //no class with name "0"
        $classes += class_parents($classes[0]);
        return call_user_func_array('array_merge', 
            array_map(
                function($class) {
                    return $class::$data;
                }, 
                $classes
            )
        );
    }
}

演示here。这甚至更短。因此可以使用普通数组映射完成。不幸的是,必须手动将当前类添加到迭代层次结构数组中。