道可道,非常道;名可名,非常名。
从逻辑上讲,
首先我们按照这个原则,来清理一下我们之前Student类所使用过的字段:
所以,我们来看这段代码:
internal class Student { static string at = "源栈"; string _name; void learn(int score) { Console.WriteLine($"{_name}在{at}学习……"); score++; } }实例方法learn()中使用了静态字段at,实例化一个学生,然后调用他的learn()方法是OK的:
Student zjq = new Student("曾俊清"); zjq.learn(95);
因为zjq(以及其他所有Student的对象)学习的地方确实就是Student类定义的源栈。
反之……反之不过来,因为学习应该是某个同学的学习,不能是一个类的学习。
深入C#底层,
面向对象其实就是映射现实。
@想一想@:
class Exam //想到“考试”可以是个类 { public void Attend() { } }
//返回的是Score类,不是int或float //传入的参数是Student,不是string public Score Attend(Student student) { }
class YzStudent { //不是string TeacherName public Teacher Teacher;
后面我们还会学到:(C#中)包括int、string、bool、数组……全都是类型,他们所对应的数据,全部都是对象。
为什么呢?因为静态代表的是类,不能代表对象,所以不能体现出面向对象的优势。你看,我们说的是面向“对象”,而不是说的面向“类”。
前面我们讲过,引入面向对象,是为了“分门别类”的归纳管理数量众多的方法,但这只是原因之一,而且是最低层次的原因。更重要的是,我们可以通过对象(而不是类),进一步的优化我们的代码。
几乎没办法传递,方法的参数和返回值,能够用静态类/数据么?
都是对象!
比较适合的静态方法可以是“报到(enroll)”,把已经报到的学生信息存放起来:
//用一个静态数组存放所有入栈学生 static Student[] students = new Student[18];存储所有同学的数组,应该是属于整个Student的,不应该属于任何一个学生。否则就会造成:
//要逐渐习惯使用简单类型以外的自定义类型 public static void enroll(Student newbie) { for (int i = 0; i < students.Length; i++) { //找到一个为null值的“空位” if (students[i] == null) { //把新同学放到空位中 students[i] = newbie; return; } } }
同时,从逻辑上来说,给新同学报到这件事,不应该任何一个同学都可以做,张三给李四报道?
交给Student的类来做比较合适,所以应该是static的(当然,你一定要把方法写成实例的也不违反语法,只是会怪怪的)。
好的方法有一个特点:参数个数要少。
还记得我们之前表示学生注册的enroll(Student)方法么?引入Student,将Student作为一种数据容器,减少方法参数个数,所以我们enroll()的参数就是一个Student对象。
但是,不要止步于此!
还能进一步的减少参数么?可以的:
void enroll(/*没有参数了*/) { //使用自己的Name Console.WriteLine($"{Name}注册了"); }这就是实例方法的典型应用:尽可能的用对象自有的数据来完成方法,而不是依赖于方法参数传递。
Student wx = new Student { Name = "王新" }; wx.enroll();
你可能觉得有点怪异:为什么自己可以给自己报到呢?
Good Question,这里的“可以”是一个关键词。当我们说一个对象/类“可不可以”干一件事的时候,究竟指的是什么?注意,“可不可以”靠的是“能力”,而不是“权限”。而所谓能力,就依靠于对象所拥有的“资源”即:数据和方法。
Student对象可以报到(enroll),或者说可以把enroll()方法放置到Student类中,是因为它拥有了报到所需要的资源,比如学生姓名、年龄、预缴订金等等,凭借这些数据(以及方法),就可以完成enroll()方法需要完成的功能。
一个对象的方法可以完全依赖于对象本身完成其功能,不带一个参数,这就是一种理想的面向对象的设计。
@想一想@:
问题的本质:发布一篇文章是谁的职责?
如何确定类/对象的职责?看它的能力(资源)。
假设文章发布时,要:
class User { public string name; public Article[] articles; //为什么就不是static的呢?对比Student.enroll() public int bMoney;
class Article { public string title; public User author;
核心在于Article里有没有,要不要User author:
public void Publish() { author.bMoney--; Console.WriteLine(title); //article 添加到 articles }
csharp.author = fg; csharp.Publish(); //内聚 vs 耦合
public void Publish(Article article) { bMoney--; Console.WriteLine(article.title); //article 添加到 articles }
fg.Publish(csharp);
多快好省!前端后端,线上线下,名师精讲
更多了解 加: