首先,我理解接口或抽象类(在.NET/C#术语中)不能具有抽象静态方法的原因.我的问题更侧重于最佳设计解决方案.
我想要的是一组"辅助"类,它们都有自己的静态方法,这样如果我从第三方供应商那里得到对象A,B和C,我可以使用诸如
AHelper.RetrieveByID(string id); AHelper.RetrieveByName(string name); AHelper.DumpToDatabase();
由于我的AHelper,BHelper和CHelper类都基本上都有相同的方法,因此将这些方法移动到这些类随后派生的接口似乎是有意义的.但是,希望这些方法是静态的,使我无法使用通用接口或抽象类来导出所有这些方法.
我总是可以使这些方法非静态,然后首先实例化对象,如
AHelper a = new AHelper(); a.DumpToDatabase();
但是,这段代码对我来说似乎并不直观.你有什么建议?我应该完全放弃使用接口或抽象类(我现在的情况)还是可以重构这些以完成我正在寻找的设计?
为什么以下代码打印"Main"?
public class Main
{
public static void method()
{
System.out.println("Main");
}
public static void main(String[] args)
{
Main m = new SubMain();
m.method();
}
}
class SubMain extends Main
{
public static void method()
{
System.out.println("SubMain");
}
}
Run Code Online (Sandbox Code Playgroud)
在运行时,m指向一个实例Submain,因此它应该在概念上打印"SubMain".
int g() {
cout << "In function g()" << endl;
return 0;
}
class X {
public:
static int g() {
cout << "In static member function X::g()" << endl;
return 1;
}
};
class Y: public X {
public:
static int i;
};
int Y::i = g();
Run Code Online (Sandbox Code Playgroud)
最初我认为,当符号解析从最内部范围到最外部范围发生时,这就是为什么要调用x :: g().
但后来我密切注意到了这段代码
int Y::i = g();
Run Code Online (Sandbox Code Playgroud)
如何在没有名称范围的情况下访问X :: g()?
这个陈述所在的范围应该是全局的,而不是Y ::或X ::,所以符号解析应该给出函数g()的全局版本?
我可以将Python方法同时定义为静态和实例吗?就像是:
class C(object):
@staticmethod
def a(self, arg1):
if self:
blah
blah
Run Code Online (Sandbox Code Playgroud)
所以我可以用它们来调用它:
C.a(arg1)
C().a(arg1)
Run Code Online (Sandbox Code Playgroud)
目的是能够运行两组逻辑.如果作为实例方法访问,它将使用实例变量并执行操作.如果作为静态方法访问,它将不会.
这是一个学术问题,不仅仅是一个实际问题.我正在尝试深入研究Python的基础,我想知道:如果我愿意,我可以在纯Python中实现staticmethod和classmethod装饰器吗?
对于staticmethod也许我可以保持一个参照原有的功能,并调用它省略了第一个参数?
对于classmethod也许我可以保持一个参照原有的功能,并把它传递的第一个参数的类型,而不是争论本身?(我怎么处理它直接在课堂上调用?)
同样,并不是我想在我的程序中实际实现它; 我想学习语言是如何运作的.如果有可能,我会非常感谢代码示例.如果没有,我希望解释为什么理论上无法做到.谢谢!
编辑:感谢您的答案和描述符协议的参考!作为进一步扩展我对Python的理解的一种方法,我想再问两件事:
这可以在没有描述符协议的情况下完成,例如在我们的类中实现__ call __特殊方法吗?
描述符协议在Python 2.7和Python 3.x中的工作方式是否相同?
再次感谢!
我一直在审查Java Regex库,因为这个Pattern类没有我多年来认为理所当然的公共构造函数这一事实感到惊讶.
我怀疑使用静态compile方法支持构造函数的一个原因可能是构造函数总是返回一个新对象,而静态方法可能会返回先前创建的(和缓存的)对象,前提是模式字符串是相同的.
但是,如下所示,情况并非如此.
public class PatternCompiler {
public static void main(String[] args) {
Pattern first = Pattern.compile(".");
Pattern second = Pattern.compile(".");
if (first == second) {
System.out.println("The same object has been reused!");
} else {
System.out.println("Why not just use constructor?");
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用静态方法而不是构造函数的任何其他强有力的理由?
编辑:我在这里找到了一个相关的问题.那里的答案都没有说服我.通过阅读所有答案,我感觉静态方法相对于公共构造函数在创建对象方面具有相当多的优势,而不是相反.真的吗?如果是这样,我将为我的每个类创建这样的静态方法,并安全地假设它更具可读性和灵活性.
java constructor static-methods design-patterns factory-pattern
我一直在学习我的软件开发课程,并从一个样本中发现了这个问题:
"为什么在Java方法前面同时使用静态和最终修饰符是没有意义的?"
我已经进行了一些研究,无论我去哪里都说这不是一种不好的做法,并且有充分的理由这样做 - 例如,这个stackoverflow问题: 声明一个最终的静态方法是一个坏主意吗?
那么,这个问题本身是荒谬的,还是对这个问题有合理的答案?
(此样本文件没有给出解决方案)
在PHP laravel中,我们有类似的代码
$user = User::find(1);
var_dump($user->name);
Run Code Online (Sandbox Code Playgroud)
我不关心如何使用该find方法,我关心为什么laravel使用静态方法?不应该使用静态方法使方法难以测试?
如果他们使用单身人士设计会更好吗?
例如
$user = User::getInstance()->find(1);
var_dump($user->name);
Run Code Online (Sandbox Code Playgroud) 当我试图在javascript中从构造函数调用静态方法时,它表示该方法不存在.
class TestClass {
constructor(){
this.staticMethod();
}
static staticMethod() {
}
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试从构造函数调用普通方法,这工作正常.如果静态方法属于类而不是实例,为什么它不允许它们从构造函数调用?
我有一个静态成员的类.这将使用同一个类的私有静态函数进行初始化.
#include <iostream>
#include <string>
class A
{
public:
static std::string const s;
private:
static std::string make()
{
return "S";
}
};
std::string const A::s = A::make();
int main()
{
std::cout << A::s << std::endl;
// std::cout << A::make() << std::endl; // <-- Does not work
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:由于这个规则是允许的吗?很明显,评论的部分不起作用,因为我不允许从课外访问私人函数.那么为什么在启动期间私有静态成员的初始化是一个特殊情况呢?(并且在旁注:这条规则的目的是什么?是否允许这个确切的情况?)
我知道其他初始化静态成员的机制(如下所示:初始化私有静态成员).但在我的情况下,成员是const,所以据我所知,设置它的唯一方法是通过定义位置的直接初始化.
c++ static-methods initialization static-members language-lawyer
static-methods ×10
java ×3
c++ ×2
python ×2
.net ×1
class-method ×1
constructor ×1
decorator ×1
descriptor ×1
ecmascript-6 ×1
inheritance ×1
javascript ×1
laravel ×1
php ×1
singleton ×1