本篇文章给大家谈谈python类方法,以及python类方法和静态方法的知识点,同时本文还将给你拓展java通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包、javascript类属性、类
本篇文章给大家谈谈python 类方法,以及python类方法和静态方法的知识点,同时本文还将给你拓展java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包、javascript 类属性、类方法、类实例、实例属性、实例方法、LINQ to Object—— 立即执行的 Enumerable 类方法、OC学习笔记九 类方法等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:- python 类方法(python类方法和静态方法)
- java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包
- javascript 类属性、类方法、类实例、实例属性、实例方法
- LINQ to Object—— 立即执行的 Enumerable 类方法
- OC学习笔记九 类方法
python 类方法(python类方法和静态方法)
http://www.cnpythoner.com/post/308.htmlhttp://www.cnpythoner.com/post/308.html
python类里会出现这三个单词,self和cls都可以用别的单词代替,类的方法有三种,
一是通过def定义的 普通的一般的,需要至少传递一个参数,一般用self,这样的方法必须通过一个类的实例去访问,类似于c++中通过对象去访问;
二是在def前面加上@classmethod,这种类方法的一个特点就是可以通过类名去调用,但是也必须传递一个参数,一般用cls表示class,表示可以通过类直接调用;
三是在def前面加上@staticmethod,这种类方法是静态的类方法,类似于c++的静态函数,他的一个特点是参数可以为空,同样支持类名和对象两种调用方式;
代码:
[python] view plaincopy
class A:
member = "this is a test."
def __init__(self):
pass
@classmethod
def Print1(cls):
print "print 1: ", cls.member
def Print2(self):
print "print 2: ", self.member
@classmethod
def Print3(paraTest):
print "print 3: ", paraTest.member
@staticmethod
def print4():
print "hello"
a = A()
A.Print1()
a.Print1()
#A.Print2()
a.Print2()
A.Print3()
a.Print3()
A.print4()
java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包
首先自定义三个类
package reflection1;
public interface MtInterface {
void info();
}
package reflection1;
import java.io.Serializable;
public class Creature<T> implements Serializable {
private char gender;
public double weight;
private void breath() {
System.out.println("呼吸");
}
public void eat() {
System.out.println("吃饭");
}
}
package reflection1;
public class Person extends Creature<String> implements Comparable<String>,MtInterface {
private String name;
int age;
public int id;
public Person() {
super();
}
private Person(String name) {
super();
this.name = name;
}
Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person(String name, int age, int id) {
super();
this.name = name;
this.age = age;
this.id = id;
}
private String show(String nation) {
System.out.println("nation="+nation);
return nation;
}
public String display(String interests) {
return interests;
}
@Override
public void info() {
System.out.println("我是人");
}
@Override
public int compareTo(String o) {
return 0;
}
private static void showDesc() {
System.out.println("i am zsben");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", id=" + id + "]";
}
}
然后通过反射获取类属性结构
package reflection2;
import java.lang.module.ModuleDescriptor.Exports.Modifier;
import java.lang.reflect.Field;
import org.junit.jupiter.api.Test;
import reflection1.*;
/*
* 获取当前运行时类的属性结构
* */
public class FieldTest {
@Test
public void test1() {
Class clazz = Person.class;
//获取属性结构
//getFields():获取当前运行时类及其父类中所有public的属性
Field [] fields = clazz.getFields();
for(Field f:fields)
System.out.println(f);
System.out.println("");
//getDeclaredFields():获得当前运行时类的所有属性,不包含父类的属性,不考虑权限
fields = clazz.getDeclaredFields();
for(Field f:fields)
System.out.println(f);
System.out.println("");
}
//权限修饰符:数据类型 变量名
@Test
public void test2() {
Class clazz = Person.class;
Field [] fields = clazz.getDeclaredFields();
for(Field f:fields) {
System.out.println(f);
//1.权限修饰符
int modifiers = f.getModifiers();
System.out.println(modifiers);
//2.数据类型
Class type = f.getType();
System.out.println(type);
//3.变量名
String name = f.getName();
System.out.println(name);
System.out.println("");
}
}
}
获取类方法
package reflection2;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;
import reflection.Person;
/*
* 获取运行时类的方法结构
*
* */
public class MethodTest {
@Test
public void test1() {
Class clazz = Person.class;
//getMethods():获取当前类及其父类所有public方法
Method[] methods = clazz.getMethods();
for(Method m:methods) {
System.out.println(m);
}
System.out.print(''\n'');
//获取当前运行时类中的所有方法
methods = clazz.getDeclaredMethods();
for(Method m:methods) {
System.out.println(m);
}
}
/*
* 权限修饰符,返回值类型,方法名(参数类型1 参数1,参数类型2 参数2,参数类型3 参数3...)
* */
@Test
public void test2() {
//1.获取方法声明的注解
Class clazz = Person.class;
Method[]methods = clazz.getDeclaredMethods();
for(Method m:methods) {
System.out.println(m);
//1.获得方法声明的注解
Annotation[] annos = m.getAnnotations();
for(Annotation a:annos) {
System.out.println(a);
}
//2.获取权限修饰符
int modifier = m.getModifiers();
System.out.println(modifier);
//3.返回值类型
System.out.println(m.getReturnType().getName());
//4.方法名
System.out.println(m.getName());
//5.形参列表
Class [] parameterTypes = m.getParameterTypes();
if(!(parameterTypes == null && parameterTypes.length==0)) {
for(int i=0;i<parameterTypes.length;i++) {
Class p = parameterTypes[i];
System.out.println(p.getName()+" args_"+i);
}
}
//6.抛出的异常
Class [] exceptionTypes = m.getExceptionTypes();
for(Class e:exceptionTypes)
System.out.println(e.getName());
}
}
}
父类及其泛型,所在包,接口
package reflection2;
import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import reflection1.Person;
public class OtherTest {
/*
* 获取构造器结构
* */
@Test
public void test1() {
Class clazz = Person.class;
Constructor[] constructors = clazz.getConstructors();
for(Constructor c:constructors)
System.out.println(c);
System.out.println();
constructors = clazz.getDeclaredConstructors();
for(Constructor c:constructors)
System.out.println(c);
}
/*
* 获取运行时类的父类
* */
@Test
public void test2() {
Class clazz = Person.class;
Class superClass = clazz.getSuperclass();
System.out.println(superClass);
}
/*
* 获取运行时带泛型的父类
* */
@Test
public void test3() {
Class clazz = Person.class;
Type superClass = clazz.getGenericSuperclass();
System.out.println(superClass);
}
/*
* 获取运行时带泛型的父类的泛型
* */
@Test
public void test4() {
Class clazz = Person.class;
Type superClass = clazz.getGenericSuperclass();
ParameterizedType paramType = (ParameterizedType)superClass;
//获取泛型类型
Type[] types = paramType.getActualTypeArguments();
System.out.println(types[0].getTypeName());
}
/*
* 获取运行时类的接口
* */
@Test
public void test5() {
Class clazz = Person.class;
Class[] interfaces = clazz.getInterfaces();
for(Class c:interfaces)
System.out.println(c);
System.out.println();
Class[]interfaces1 = clazz.getSuperclass().getInterfaces();
for(Class c:interfaces1)
System.out.println(c);
}
/*
* 获取类运行时所在包
* */
@Test
public void test6() {
Class clazz = Person.class;
Package package1 = clazz.getPackage();
System.out.println(package1);
}
}
javascript 类属性、类方法、类实例、实例属性、实例方法
1: <script>
2: function Circle( radius ){
3: this.r = radius;
4: this.des = "圆形";
5:
6: this.showInfo = function(){
7: alert("这是一个"+this.des);
8:
9: }
10: }
11:
12: function Circle_area(r){ return Circle.PI*this.r*this.r; }
13:
14: function Circle_perimeter(r){ return 2*Circle.PI*r;}
15:
16: Circle.PI = 3.14;
17: Circle.perimeter = Circle_perimeter;
18: Circle.prototype.area = Circle_area;
19:
20: var c = new Circle(3);
21:
22: //测试类属性
23: //alert(Circle.PI )//3.14
24: //alert(c.PI)//undefined 因为类属性是和类本身,也就是函数本身相关联的,和类实例没有直接关系。
25: //alert(c.constructor.PI)//3.14 如果想通过类实例访问类属性,那么就需要先访问该实例的构造函数,进而访问该类属性
26: //alert(Circle.des)//undefined 因为函数Circle函数中的this.des中的this指代的不是函数本身,而是调用r的对象,而且只能是对象。
27: //alert(c.des)//圆形 this此时为实例化的 对象c。
28:
29: /*结论:
30: 面向对象的角度:类属性是类对象的直接属性,且该属性与基于该类对象生成的实例对象没有直接关系,无法直接调用。
31: 可以直接通过 类名.属性名 调用该类属性。如果想通过该类对象的实例对象调用类属性,那么可以使用 对象实例.constructor属性
32: 调用该对象的类对象,然后通过类对象调用其类属性
33: javascript函数角度:类属性是javascript函数对象的直接属性变量(这里之所以称之为属性变量是由于javascript变量和属性的同一
34: 性),且该属性变量与基于该函数对象构造出来的对象引用(生成了一个对象,这个对象实际上是一个空对象,并且保存了对构造
35: 函数以及构造函数初始化时函数内部this关键字下的相关属性和函数的引用[c.prototype和构造函数中this.下面的相关属性、函数]:)
36: 没有直接关系,如果想通过基于构造函数生成的对象c调用构造函数对象的属性变量PI,那么需要通过c.constructor属性找到该构造
37: 函数对象,并通过该对象获取其属性变量。
38: */
39:
40: //测试类方法
41: //alert(Circle.perimeter(3)); //18.4 直接调用函数的类方法。
42: //alert( c.perimeter(3) ); //FF:c.perimeter is not a function IE:对象或属性不支持此方法。因为perimeter函数是Circle类的类方法,和实例对象没有直接关系
43: //alert(c.constructor.perimeter(3));//18.84 调用该对象构造函数(类函数)的方法(函数)。
44: //alert(c.area(3))//28.25.... Circle类的prototype原型属性下的area方法将会被Circle类的实例对象继承。
45: //alert(Circle.area(3));//FF: 错误: Circle.area is not a function 因为area方法是Circle类的原型属性的方法,并不是Circle类的直接方法。
46:
47: //结论:同上,把属性换成了方法,把属性变量换成了函数。
48:
49: //测试prototype对象属性
50: //alert(c.prototype); //undefined 实例对象没有ptototype属性
51: //alert(Circle.prototype); //object Object
52: //alert(Circle.prototype.constructor)//返回Circle的函数体(函数代码体),相当于alert(Circle)
53: //alert(Circle.prototype.area(3));//NaN 方法调用成功,但是返回结果却是NaN,原因是area函数内部的this.r是undefined。
54: //alert(Circle.prototype.PI) //undefined因为PI属性是Circle类函数的直接属性,并不会在prototype属性下存在
55: //alert(Circle.prototype.constructor.PI)//3.14 通过Circle类的原型对象调用该原型对象的构造函数(类函数),再通过类函数调用PI属性。
56:
57: /*结论:prototype原型对象是javascript基于原型链表实现的一个重要属性。
58: Javascript角度:1. 实例对象没有prototype属性,只有构造函数才有prototype属性,也就是说构造函数本身保存了对prototype属性
59: 的引用。。2. prototype属性对象有一个constructor属性,保存了引用他自己的构造函数的引用(看起来像是个循环:A指向B,B指向A...)
60: 3.prototype对象(不要被我这里的属性对象,对象,对象属性搞晕乎了,说是属性对象,就是说当前这个东西他首先是某个对象的属性,
61: 同时自己也是个对象。对象属性就是说它是某个对象的属性。)的属性变量和属性对象将会被该prototype对象引用的构造函数所创建的
62: 对象继承(function A(){} A.prototype.pa = function(){} var oA = new A(); 那么oA将会继承属性函数pa)。
63: */
64:
65: /*这里对 对象属性,对象方法不再做详细测试。
66: 1.javascript对象实例的在通过其构造函数进行实例化的过程中,保存了对构造函数中所有this关键字引用的属性和方法的引用(这里不
67: 讨论对象直接量语法的情况)。但如果构造函数中没有通过this指定,对象实例将无法调用该方法。2.javascript可以通过构造函数创建
68: 多个实例,实例会通过__proto__属性继承原型对象的属性和方法。如果对实例对象的属性和方法进行读写操作,不会影响其原型对象的
69: 属性和方法,也就是说,对于原型对象,javascript实例对象只能读,不能写。那当我们对实例对象的属性和方法进行修改的时候也可以
70: 改变其值这是为什么呢?其实当我们试图在实例对象中使用继承自原型对象的属性或方法的时候,javascript会在我们的实例对象中复
71: 制一个属性或方法的副本,这样,我们操作的时候,其实操作的就是实例对象自己的属性或方法了。
72:
73:
74: */
75: //测试__proto__属性
76: //alert(c.__proto__)//FF:object IE8:undefined 该属性指向Circle.prototype,也就是说调用该对象将会返回Circle的prototype属性。
77: //由于IE8及以下版本不支持__proto__属性,所以以下结果都在FF下得出。
78: //alert(c.__proto__.PI)//undefined 因为函数原型下面没有PI属性,PI是类函数Circle的直接属性
79: //alert(c.__proto__.area(3))//NaN 该函数执行成功,返回值为NaN是由于函数体中的this.r为undefined。
80:
81: /*结论:__proto__属性保存了对创建该对象的构造函数引用prototype属性的引用,也就是说构造函数可以引用prototype,基于该构
82: 造函数生成的实例也可以引用,只不过引用的方式不一样。*/
83: </script>
ps: 对于 b.__proto__ 和 B.prototype 和 b.constructor.prototype 指向同一个地方。
LINQ to Object—— 立即执行的 Enumerable 类方法
前面说到 LINQ to Object—— 延时执行的 Enumerable 类的方法,接下来说说 LINQ to Object—— 立即执行的 Enumerable 类方法。
1.ToArray 序列转换成数组
List<string> names_list = new List<string> { "张三", "范冰冰", "李冰冰", "迈克尔·杰克逊", "李四", "王五", "赵六", "田七" };
string[] takenames_arry = names_list.ToArray();
string[] takenames_arry2 = (from name in names_list
select name).Take(4).ToArray();
foreach (var name in takenames_arry2)
{
Console.WriteLine(name);
}
Console.WriteLine("----------------------------");
Console.ReadKey();
运行结果:
2.ToList 序列转换成 List<T>
string[] names_array = { "张三", "范冰冰", "李冰冰", "迈克尔·杰克逊", "李四", "王五", "赵六", "田七" };
List<string> takenames_list = names_array.ToList();
List<string> takenames_list2 = (from name in names_array select name).Skip(4).ToList();
foreach (var name in takenames_list2)
{
Console.WriteLine(name);
}
Console.WriteLine("----------------------------");
Console.ReadKey();
运行结果:
3.ToDictionary 把序列转换为泛型 Dictionary<TKey,TValue>
List<Person> personList = new List<Person>()
{
new Person(){ Name = "张三", Age = 12, Phone = "555555"},
new Person(){ Name = "李四", Age = 23, Phone = "666666"},
new Person(){ Name = "王五", Age = 14, Phone = "777777"},
new Person(){ Name = "赵六", Age = 25, Phone = "888888"},
new Person(){ Name = "田七", Age = 16, Phone = "999999"},
};
Dictionary<string, Person> dictionary_person = personList.ToDictionary(guest => guest.Name);
foreach (var person in dictionary_person)
{
Console.WriteLine("键:{0}——值:{1} {2} {3}", person.Key, person.Value.Name, person.Value.Age, person.Value.Phone);
}
Console.WriteLine("--------------------------------");
Console.ReadKey();
Dictionary<string, string> dictionary_person2 = personList.ToDictionary(person => person.Name, person => person.Phone);
foreach (var person in dictionary_person2)
{
Console.WriteLine("键:{0}——值:{1}", person.Key, person.Value);
}
Console.WriteLine("--------------------------------");
Console.ReadKey();
运行结果:
注意:Dictionary 的 Key 和 Value 是一一对应关系。
4.ToLookup 用于将序列转换为泛型 Lookup<TKey,TValue>
和 ToDictionary 类似,不细写代码了。
注意:Lookup 的 Key 和 Value 是一对多关系,Lookup 没有公共构造函数,只能用 ToLookup 构建,创建后也不能删除 Lookup 中的元素。
5.SequenceEqual 比较两个序列是否相等
bool sequence_equal = names_array.SequenceEqual(names_list);
bool sequence_equal2 = names_array.Skip(1).Take(2).SequenceEqual(names_list.Take(3).SkipWhile(n => n.Length == 2));
Console.WriteLine("{0},{1}", sequence_equal, sequence_equal2);
Console.WriteLine("----------------------------");
Console.ReadKey();
运行结果:
6.First 返回序列第一个满足条件元素
var first_name = names_array.First();
var first_name2 = names_array.First(n => n.Length == 3);
Console.WriteLine("{0},{1}", first_name, first_name2);
Console.WriteLine("----------------------------");
Console.ReadKey();
运行结果:
7.FirstOrDefault 返回序列第一个满足条件元素,如果没有找到则返回默认值
var first_or_default_name = names_array.FirstOrDefault();
var first_or_default_name2 = names_array.FirstOrDefault(n => n == "123");
Console.WriteLine("{0},{1}", first_or_default_name, first_or_default_name2);
Console.WriteLine("----------------------------");
Console.ReadKey();
运行结果:
8.Last 返回序列最后一个满足条件元素
var last_name = names_array.Last();
var last_name2 = names_array.LastOrDefault(n => n.Length == 3);
Console.WriteLine("{0},{1}", last_name, last_name2);
Console.WriteLine("----------------------------");
Console.ReadKey();
运行结果:
9.LastOrDefault 返回序列最后一个满足条件元素,如果没有找到则返回默认值
var last_or_default_name = names_array.LastOrDefault();
var last_or_default_name2 = names_array.LastOrDefault(n => n == "123");
Console.WriteLine("{0},{1}", last_or_default_name, last_or_default_name2);
Console.WriteLine("----------------------------");
Console.ReadKey();
运行结果:
10.Single 返回序列中唯一的元素,注意:如果序列中包含多个元素,会引发运行错误
try
{
var single_name = names_array.Single();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("----------------------------");
var single_name2 = names_array.Single(n => n == "张三");
Console.WriteLine("{0}", single_name2);
Console.WriteLine("----------------------------");
Console.ReadKey();
运行结果:
11.SingleOrDefault 找出序列中满足一定条件的元素,注意:如果序列为空则返回默认值, 如果序列中包含多个多个元素会引发运行错误
try
{
var single_or_default_name = Enumerable.Empty<int>().SingleOrDefault();
Console.WriteLine("{0}", single_or_default_name);//不报错,如果序列为空就返回默认值
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("----------------------------");
try
{
var single_or_default_name2 = names_array.SingleOrDefault();
Console.WriteLine("{0}", single_or_default_name2);//报错,序列包含多行错误
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("----------------------------");
var single_or_default_name3 = Enumerable.Empty<string>().DefaultIfEmpty("默认值").SingleOrDefault();
Console.WriteLine("{0}", single_or_default_name3);
Console.WriteLine("----------------------------");
var single_or_default_name4 = names_array.SingleOrDefault(n => n == "123");
Console.WriteLine("{0}", single_or_default_name4);
Console.WriteLine("----------------------------");
Console.ReadKey();
运行结果:
12.ElementAt 获得指定索引处的元素
var element_at_name = names_array.ElementAt(3);
Console.WriteLine("{0}", element_at_name);
Console.WriteLine("----------------------------");
Console.ReadKey();
运行结果:
13.ElementAtOrDefault 获得指定索引处的元素,如果超出索引,则返回元素类型的默认值
var element_at_or_default_name = names_array.ElementAtOrDefault(5);
var element_at_or_default_name2 = names_array.ElementAtOrDefault(10);
Console.WriteLine("{0},{1}", element_at_or_default_name, element_at_or_default_name2);
Console.WriteLine("----------------------------");
Console.ReadKey();
运行结果:
14.All 序列中的所有元素是否都满足条件
bool all_names = names_array.All(s => s.GetTypeCode() == TypeCode.String);
bool all_names2 = names_array.All(s => s.Length < 10);
Console.WriteLine("{0},{1}", all_names, all_names2);
Console.WriteLine("----------------------");
Console.ReadKey();
运行结果:
15.Any 序列中的元素是否存在或满足条件
bool any_names = names_array.Any();
bool any_names2 = names_array.Any(s => s.Length > 7);
Console.WriteLine("{0},{1}", any_names, any_names2);
Console.WriteLine("----------------------");
Console.ReadKey();
运行结果:
16.Contains 确定元素是否在序列中
bool contains_name = names_array.Contains("田");
Console.WriteLine("{0}", contains_name);
Console.WriteLine("----------------------");
Console.ReadKey();
运行结果:
17.Count 序列包含元素的数量
int count_names = names_array.Count();
int count_names2 = names_array.Count(n => n.Length == 7);
Console.WriteLine("{0},{1}", count_names, count_names2);
Console.WriteLine("----------------------");
Console.ReadKey();
运行结果:
18.LongCount 获取一个 Int64 类型的元素数量
long longcount_names = names_array.LongCount();
long longcount_names2 = names_array.LongCount(n => n.Length == 3);
Console.WriteLine("{0},{1}", longcount_names, longcount_names2);
Console.WriteLine("----------------------");
Console.ReadKey();
运行结果:
19.Aggregate 将序列元素进行累加
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 21, 22, 232, 8, 64, 9, 46, 7 };
int aggregate_numbers = numbers.Aggregate((n1, n2) => n1 + n2);
int aggregate_numbers2 = numbers.Aggregate(99, (n1, n2) => n1 + n2);
Console.WriteLine("{0},{1}", aggregate_numbers, aggregate_numbers2);
Console.WriteLine("----------------------");
Console.ReadKey();
string aggregate_names = names_array.Aggregate((name1, name2) => string.Format("{0}、{1}", name1, name2));//相当于name1 += name2
string aggregate_names2 = names_array.Aggregate("累加结果:", (name1, name2) => string.Format("{0}、{1}", name1, name2));
Console.WriteLine("{0}", aggregate_names);
Console.WriteLine("{0}", aggregate_names2);
Console.WriteLine("----------------------");
Console.ReadKey();
运行结果:
20.Sum 序列之和
21.Average 序列平均值
22.Min 序列的最小值
23.Max 序列的最大值
//20、Sum序列之和
int sum_numbers = numbers.Sum();
Console.WriteLine(sum_numbers);
Console.WriteLine("----------------------");
//21、Average序列平均值
double avg_numbers = numbers.Average();
Console.WriteLine(avg_numbers);
Console.WriteLine("----------------------");
//22、Min序列的最小值
int min_numbers = numbers.Min();
Console.WriteLine(min_numbers);
Console.WriteLine("----------------------");
//23、Max序列的最大值
int max_numbers = numbers.Max();
Console.WriteLine(max_numbers);
Console.WriteLine("----------------------");
Console.ReadKey();
运行结果:
常用立即执行的 Enumerable 类方法学习和整理完毕!
OC学习笔记九 类方法
在OC 中,通过类直接调用的方法叫类方法,类方法执行效率高,但不能访问成员变量,通常用作于 工具方法
一声明部分
@interface Calculator : NSObject
{
@public
int _sum;
int _avg;
}
/*
对象方法:
1.以-开头
*/
-(int)sumWithNum:(int)num1 andNum:(int)num2;
-(int)avgWithNum:(int)num1 andNum:(int)num2;
/*
类方法:
1.以+开头
2.类方法可以和对象方法同名,系统会根据方法类型来区分
*/
+(int)sumWithNum:(int)num1 andNum:(int)num2;
+(int)avgWithNum:(int)num1 andNum:(int)num2;
@end
二 实现部分
@implementation Calculator
-(int)sumWithNum:(int)num1 andNum:(int)num2
{
//对象方法可以访问成员变量
_sum = num1+num2;
return _sum;
}
-(int)avgWithNum:(int)num1 andNum:(int)num2
{
//在对象方法中,可以直接访问类方法
return [Calculator sumWithNum:num1 andNum:num2]/2;
}
+(int)sumWithNum:(int)num1 andNum:(int)num2
{
/*
类方法如果直接访问成员变量则报
_sum = [[Calculator new] sumWithNum:num1 andNum:num2];
instance varlalbe ''_sum'' accessed in class method
[[Calculator new] sumWithNum:num1 andNum:num2]
注意:在类方法中调用对象方法必须创建对象, 一般开发中不建议这样使用
*/
return [[Calculator new] sumWithNum:num1 andNum:num2];
}
+(int)avgWithNum:(int)num1 andNum:(int)num2
{
return (num1+num2)/2;
}
@end
三 主函数
int main(int argc, const char * argv[])
{
/*
对象方法:
1.通过对象调用 [[ClassName new] functionName]
2.以+开头
3.可以访问成员变量
*/
Calculator *c = [Calculator new];
int _sum = [c sumWithNum:3 andNum:2];
NSLog(@"对象方法调用:sum=%d",_sum);
int _avg = [c avgWithNum:4 andNum:4];
NSLog(@"对象方法调用:avg=%d",_avg);
/*
类方法:
1.通过类名调用 [ClassName functionName];
2.以+开头,其他和对象方法一样
3.执行效率高
4.不能访问成员变量
*/
_sum = [Calculator sumWithNum:15 andNum:20];
NSLog(@"类方法调用:sum=%d",_sum);
_avg = [Calculator avgWithNum:4 andNum:4];
NSLog(@"类方法调用:avg=%d",_avg);
return 0;
}
总结
方法名 | 声明方式 | 调用方式 | 成员变量访问 | 调用对象方法 | 调用类方法 |
对象方法 | -开头 | 对象调用 | 可以访问 | 直接调用 | 直接调用 |
类方法 | +开头 | 类调用 | 不能访问 | 不能直接调用 | 直接调用 |
类方法的优点:
不依赖于类
执行效率高
类方法运用场景:
不需要使用成员变量的方法
用于编写工具方法
关于python 类方法和python类方法和静态方法的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包、javascript 类属性、类方法、类实例、实例属性、实例方法、LINQ to Object—— 立即执行的 Enumerable 类方法、OC学习笔记九 类方法的相关知识,请在本站寻找。
本文标签: