当前位置: 首页 > 知识库问答 >
问题:

父类为子类定义静态类

齐威
2023-03-14

想知道是否有一种在Java中实现这一点的方法。

想象一下,我想创建一个父类(可能是抽象的)并创建多个不同的子类。我希望所有类都有一个特定的字段,但我需要该字段在子上下文中是静态的。有没有办法在父类中定义它?

例如,假设我对名为Foo的字段有getter和setter。在父类中,静态字段初始化为字符串“foo”。我有两个儿童班AbsChildOne和AbsChildOne。我希望能够做到的是:

    AbsChildOne absOneA = new AbsChildOne();
    AbsChildOne absOneB = new AbsChildOne();
    AbsChildTwo absTwo = new AbsChildTwo();

    absOneA.setFoo("bar");
    System.out.println("absOneB "+absOneB.getFoo());
    System.out.println("absTwo "+absTwo.getFoo());

返回

absOne2 bar
absTwo foo

换句话说,静态字段仅对子类是静态的,而对其他子类不是静态的。

共有1个答案

姬俊驰
2023-03-14

事实是,静态处于类级别,所以每次都有一个值,每个包括子类(不要与class实例混淆)。因此,当使用静态(甚至init)时,不需要有一个实例。(

字符串s_get_static_value=ClassName.value。每次对于每个ClassName_instances,在一个时间点只有一个值适用于所有实例。因此一旦改变(在类级别,实例)将反映到所有实例(隐含类级别)。

关键是,您不能保持从同一个静态派生的两个独立的静态(总是有1个值,而不是2)。

现在,如果希望有一个扩展字段父项,每个子项具有单独的值(类级别上只有1个,并且从类型派生的所有实例也可以是一个不同的子类。父类子类不同,即使子类扩展了父类)。

考虑逻辑的机会。(要求:与你的相同,但没有静态)

//in term of field_value ; all in the same time and just 1 based on Types
parent = A (on Parent class) : Type Parent
parent = A1 (on Child1 at inhereted field from Parent) : Type Child1 
parent = A2 (on Child2 at inhereted field from Parent) : Type Child2

//oneInstance is doing that task which is an object based on Singleton
//can hold as may parameters as wanted (mystring in this case)   

也许这能帮你。

//adjusted singleton with a map which hold instances
import java.util.HashMap;

import tst.Test02.Child1;
import tst.Test02.Child2;

public class OneInstance 
{
    String myString = "";
    private OneInstance oi ;
    public static HashMap<String, OneInstance> hm = new HashMap<String,OneInstance>();
    public static OneInstance getInstance(Object o)
    {
        if(!hm.containsKey(o.getClass().toString()))
            hm.put(o.getClass().toString(), new OneInstance("default value for _"+o.getClass().toString()));
        return hm.get(o.getClass().toString());
        
    }
    public static OneInstance getInstance(Object o,String s)
    {
        if(!hm.containsKey(o.getClass().toString()))
            hm.put(o.getClass().toString(), new OneInstance(s));
        return hm.get(o.getClass().toString());
        
    }
    public static OneInstance getInstance()
    {
        if(!hm.containsKey(new Parent().getClass().toString()))
            hm.put(new Parent().getClass().toString(), new OneInstance("default value for Parent"));
        return hm.get(new Parent().getClass().toString());
    }
    
    private OneInstance() {}
    private OneInstance(String s)
    {
        
        myString = s;
    }
    
}
public class Parent 
{
    static MyObj sobj = new MyObj("static name");
    OneInstance oi;
    
    public String toString()
    {
        return "myString="+oi.getInstance().myString;
    }
}
//usage
import java.util.Set;

public class Test02 
{
    public static void main(String[] args)
    {
        Test02 t = new Test02();
        Child1 c1;
        Child2 c2;
        System.out.println("inhereted name for child1:"+Child1.sobj.name);
        Child1.sobj.name = "child1_new_name";
        System.out.println("child1 new name:"+Child1.sobj.name);
        System.out.println("inhereted name for child2:"+Child2.sobj.name);
        System.out.println("-----------");
        System.out.println(new Parent());
        c1 = t.new Child1("child1_string");
        
        //with any specification just init with parent value and keep
        System.out.println(c1);
        System.out.println(c1.oi.getInstance(c1).myString);
        System.out.println("-----------");
        
        System.out.println("dump HashMap");
        OneInstance.hm.forEach((k, v) -> System.out.println((k + ":" + v.myString)));
        System.out.println("-----------");
        c2 = t.new Child2("child2_string from constructor"); 
        c1.oi.getInstance(c1).myString = "changed for child 1";
        System.out.println(c1.oi.getInstance(c1).myString);
        System.out.println("dump HashMap");
        OneInstance.hm.forEach((k, v) -> System.out.println((k + ":" + v.myString)));
        System.out.println("-----------");
        c2 = t.new Child2("child2_string from constructor"); 
        System.out.println(c2);
        
        //System.out.println(c2.oi.getInstance(c2).myString);
        //c2.oi.getInstance(c2).myString = "changed for child 2";
        //System.out.println(c2.oi.getInstance(c2).myString);
        
        System.out.println(c1);
        System.out.println(c1.oi.getInstance(c1).myString);
        System.out.println(c2.oi.getInstance(c2).myString);
        System.out.println("dump HashMap");
        OneInstance.hm.forEach((k, v) -> System.out.println((k + ":" + v.myString)));
        System.out.println("-----------");
        
        
    }
    
    class Child1 extends Parent
    {
         //inherited
         //OneInstance oi ;
         Child1(String s)
         {
             oi = OneInstance.getInstance(this, s);
         }
         public String toString()
         {
            return "myString="+oi.getInstance(this).myString;
         }
    }
    
    class Child2 extends Parent
    {
         //OneInstance oi ;
         Child2(String s)
         {
             oi =OneInstance.getInstance(this, s);
         }
         public String toString()
         {
            return "myString="+oi.getInstance(this).myString;
         }
    }
}

输出:

inhereted name for child1:static name
child1 new name:child1_new_name
inhereted name for child2:child1_new_name
-----------
myString=default value for Parent
myString=child1_string
child1_string
-----------
dump HashMap
class tst.Test02$Child1:child1_string
class tst.Parent:default value for Parent
-----------
changed for child 1
dump HashMap
class tst.Test02$Child1:changed for child 1
class tst.Test02$Child2:child2_string from constructor
class tst.Parent:default value for Parent
-----------
myString=child2_string from constructor
myString=changed for child 1
changed for child 1
child2_string from constructor
dump HashMap
class tst.Test02$Child1:changed for child 1
class tst.Test02$Child2:child2_string from constructor
class tst.Parent:default value for Parent
-----------

关于测试,在代码开发之前。如果代码中存在逻辑错误,那么测试会带来什么?(整个测试套件将失败,并且在继续之前需要解决一些关键缺陷…)了解测试api的各种设置很好,但这不是主要范围。正确运行的代码设计,而不是出于测试目的的代码设计。(主要问题来自代码设计静态,而不是如何测试

注意:您必须添加一些逻辑以根据继承进行调整(保留字段),但是为什么不更改逻辑并允许为子项添加另一个不同的字段呢?它将更容易实现,也可以使用静态。

class Parent 
{
   static String parent;
}
class Child1 extends Parent 
{
   //inhereted
   //static String parent;

   //add a new one per subclasses
   static String child1;
}

只需比较每个场景所需的代码行,并询问它是否真的值得?度量(即使在代码行内)也在质量代码中起作用。

 类似资料:
  • 问题内容: 当静态方法在子类中被重写时,我对它的行为感到困惑。 下面是代码: 为什么在第二种情况下在这里调用超类的静态方法? 如果方法不是静态的,则根据多态性,当在运行时传递子类对象时,将调用子类的方法。 问题答案: 静态方法的解析始终基于类型。 代码 编译后转换为此 对此,它是对方法的调用而不是对子类方法的调用。因此,您将获得方法的输出。

  • 问题内容: 我在构建ORM库时要考虑到重用和简单性。一切都进行得很好,除了我被愚蠢的继承限制所困。请考虑以下代码: 显然,这不是我所期望的行为(尽管实际行为也很有意义)。因此,我的问题是,你们是否知道在父类中获得子类名称的意思。 问题答案: 简而言之。这不可能。在php4中,您可以实施可怕的破解(检查),但是该方法在PHP5中不起作用。参考资料: 37684 34421 编辑 :PHP 5.3中后

  • 为什么我们不能在子类B中声明一个实例方法,它与父类a中的静态方法共享相同的签名? 在上面的代码中,由于A没有该名称的实例方法,并且由于Java允许对象访问静态方法,所以指向B的类型为A的对象A可以调用它中存在的静态方法(类A)。但是编译器抛出一个错误“实例方法不能重写静态方法”为什么? 注意:我可以理解,如果一个类不允许两个方法使用相同的方法名,即使其中一个是实例,另一个是静态的。但是我不明白为什

  • 据我所知,通常应该使用类的引用来调用静态方法,或者如果它位于静态方法或静态块中,则可以不引用直接调用它。 但当从子类静态块调用静态方法时,这是否适用? 为什么它允许这样的事情,因为静态方法不是继承的,所以应该只允许使用父类名对吗? 为什么我的子类静态块可以在没有引用或类名的情况下调用父类静态方法?

  • 问题内容: 给定以下类别: 我的目标不是像“因为在JLS中这样指定”这样的答案。我知道是的,因为JLS是12.4.1发生初始化时,其读取内容仅为: 类或接口类型T将在以下任何一种首次出现之前立即初始化: … T是一个类,并调用T声明的静态方法。 … 我对没有这样的句子是否有充分的理由感兴趣: T是S的子类,并且在T上调用S声明的静态方法。 问题答案: 我认为这与jvm规范的这一部分有关: 每个框架

  • 我有以下C 11代码(简化版): GCC 4.9.1可以很好地编译和链接此代码。另一方面,Clang 3.5.0抱怨未定义的引用: 哪个是对的?这个代码合法吗?我对静态Constexr成员规则的理解(主要基于这个问题)是,只有在获取变量的地址时才需要类外定义。但是我没有将Deriv的地址ed::信息或在任何地方使用对它的引用;我只是按值将它传递给Base构造函数。 我发现了各种变通方法: 使两个构