首先,两者本质上的区别是:静态方法是在类中使用staitc修饰
的方法,在类定义的时候已经被装载和分配
。而非静态方法
是不加static关键字的方法,在类定义时没有占用内存
,只有在类被实例化成对象时,对象调用该方法才被分配内存。
其次,静态方法
中只能调用静态成员或者方法
,不能调用非静态方法
或者非静态成员
,而非静态方法
既可以调用静态成员
或者方法
又可以调用其他的非静态成员或者方法
。
例子1:静态方法的Main方法
访问类中的非静态成员方法
。
class Test{
public int sum(int a,int b){//非静态方法
return a+b;
}
public static void main(String[] args){
int result=sum(1,2);//静态方法调用非静态方法
System.out.println("result="+result);
}?
}
结论:以上程序在编译时,会提示静态方法不能引用非静态方法的错误信息。
解决方法:
一、静态方法
只能访问静态方法和静态成员
。
class Test{
public static int sum(int a,int b){//加入static关键字,变成静态方法
return a+b;
}
public static void main(String[] args){
int result=sum(1,2);//静态方法调用静态方法
System.out.println("result="+result);
}
}
二、非静态方法要被实例化
才能被静态方法调用。
class Test{
public int sum(int a,int b){
return a+b;
}
public static void main(String[] args){
Test test=new Test();//实例化类
int result=test.sum(1,2);//调用非静态方法
System.out.println("result="+result);
}
}
Python 实例方法、类方法、静态方法的区别与作用
实例对象的权限最大
实例方法
定义:第一个参数必须是实例对象
,该参数名一般约定为“self”
,通过它来传递实例的属性和方法
(也可以传类的属性和方法
);
调用:只能由实例对象
调用。
类方法
定义:使用装饰器@classmethod
。第一个参数必须是当前类对象
,该参数名一般约定为“cls
”,通过它来传递类的属性和方法
(不能传实例的属性和方法
);
调用:类
和实例对象
都可以调用。
静态方法
定义:使用装饰器@staticmethod
。参数随意,没有“self”和“cls”参数
,但是方法体中不能使用类或实例的任何属性和方法
;
调用:类
和实例对象
都可以调用。
实例方法
简而言之,实例方法就是类的实例
能够使用的方法。这里不做过多解释。
类方法
使用装饰器@classmethod
。
原则上,类方法
是将类本身作为对象
进行操作的方法。假设有个方法,且这个方法在逻辑上采用类本身作为对象
来调用更合理,那么这个方法就可以定义为类方法
。另外,如果需要继承
,也可以定义为类方法
。
如下场景:
假设我有一个学生类和一个班级类,想要实现的功能为:执行班级人数增加的操作、获得班级的总人数, 学生类继承自班级类,每实例化一个学生,班级人数都能增加;最后,我想定义一些学生
,获得班级中的总人数
。
思考:这个问题用类方法做比较合适,为什么?因为我实例化的是学生,但是如果我从学生这一个实例中获得班级总人数
,在逻辑上显然是不合理的。同时,如果想要获得班级总人数
,如果生成一个班级的实例
也是没有必要
的。
class ClassTest(object):
__num = 0
@classmethod
def addNum(cls):
cls.__num += 1
@classmethod
def getNum(cls):
return cls.__num
# 这里我用到魔术方法__new__,主要是为了在创建实例的时候调用累加方法。
def __new__(self):
ClassTest.addNum()
return super(ClassTest, self).__new__(self)
class Student(ClassTest):
def __init__(self):
self.name = ''
a = Student()
b = Student()
print(ClassTest.getNum())
静态方法
使用装饰器@staticmethod
。
静态方法是类中的函数
,不需要实例。静态方法主要是用来存放逻辑性的代码
,逻辑上属于类
,但是和类本身没有关系,也就是说在静态方法
中,不会涉及
到类中的属性和方法
的操作。可以理解为,静态方法是个独立的、单纯的函数
,它仅仅托管于某个类的名称空间中,便于使用和维护。
譬如,我想定义一个关于时间操作
的类,其中有一个获取当前时间的函数
。
import time
class TimeTest(object):
def __init__(self, hour, minute, second):
self.hour = hour
self.minute = minute
self.second = second
@staticmethod
def showTime():
return time.strftime("%H:%M:%S", time.localtime())
print(TimeTest.showTime())
t = TimeTest(2, 10, 10)
nowTime = t.showTime()
print(nowTime)
如上,使用了静态方法(函数)
,然而方法体中并没使用实例的属性和方法
(但可以通过类名调用类属性和类方法)。若要获得当前时间的字符串时,并不一定需要实例化对象
,此时对于静态方法而言,所在类更像是一种名称空间。其实,我们也可以在类外面写一个同样的函数来做这些事,但是这样做就打乱了逻辑关系,也会导致以后代码维护困难。
PS:在Python中,实际上没有像C,PHP那样的静态变量(static修饰),但姑且可将类属性看为静态变量。