មេរៀនទី១៣: ជាមួយ Inheritance

មេរៀនទី១៣: ជាមួយ Inheritance

1. អ្វីដែលហៅថា Inheritance?

Inheritance ក្នុងកម្មវិធី programming គឺជាការចាត់ជាថ្នាក់ទាំងអស់; វាទាក់ទងរវាង classes ។ ឧទាហរណ៍ កាលណាអ្នកនៅសាលារៀន អ្នកមាន លទ្ធភាពបានរៀនអំពីវិទ្យាសាស្រ្តថនិកសត្វ ។ ក្នុង Microsoft Visual C# អ្នក

មាន model នេះដោយបង្កើតពីរ classes មួយដែលហៅថាថនិកសត្វនិងមួយ ទៀតដែលហៅថា horse ហើយប្រកាស declare ដែល horse ទទួលពីថនិក សត្វ ។ inheritance នឹងបង្ហាញ model ដែលជាទំនាក់ទំនងហើយនិងចាប់

បានគ្រប់ horses ទាំងអស់គឺជាថនិកសត្វ ។ Inheritance គឺជា class មួយ ដែលទំនាក់ទំនងដូចជាទំនាក់ទំនង object relationship ។ ដែលប្រកាស declare ដែលមានទំនាក់ទំនងរួចជាស្រេចនៅក្នុង class level អ្នកធ្វើអោយ ប្រាកដដែលទំនាក់ទំនងតែងតែផ្តល់គ្រប់ objects ទាំងអស់នៃ class ។

2. ស្វែងយល់ Syntax ក្នុងជំពូកនេះទំនាក់ទំនង inheritance syntax មានសារះសំខាន់ដែល អ្នកត្រូវការដឹងពីរបៀបបង្កើត classes ដែលទទួលពី classes ផ្សេងទៀត ។ អ្នកនឹងរៀនអ្វីដែលមាននៅក្នុង syntax នេះមានន័យថាកាលណាអ្នកបាន ឃើញនៅក្នុងឯកសារ ។ មូលដ្ឋាន Classes និង Classes បានមកពី syntax សំរាប់ប្រកាស declare ដែល class មួយទទួលពី class ផ្សេងទៀតដូច

ខាងក្រោម:

class DerivedClass : BaseClass {

}

អ្នកសរសេរ C++ programmers នឹងកំណត់ចំណាំថាអ្នកមិនអាចធ្វើ ជាក់ស្តែងពីលក្ខណ: inheritance គឺជា public, private ។ ក្នុងកម្មវិធី C# inheritance គឺតែងតែចាត់ចែងច្បាស់លាស់ public ។ អ្នកសរសេរកម្មវិធី Java នឹងកត់ចំណាំថាមិនមានពាពាក្យគន្លឹះ extends ។ System.Object class គឺជា root class សំរាប់ classes ទាំងអស់ ។ ម្យ៉ាងវិញទៀត classes ទាំងអស់កំណត់ច្បាស់លាស់ពី System.Object class ។ ឧបមាថា អ្នក

ប្រកាស declare class មួយដូចនេះ:

class DerivedSubClass : DerivedClass {

}

compiler ស្ងាត់ស្ងៀមសរសេរ Code ឡើងវិញខាងក្រោមនេះ (ដែលអ្នកអាចសរសេរយ៉ាងជាក់ស្តែង ប្រសិនបើអ្នកពិតជាចង់ធ្វើប៉ុន្តែវាមិនល្អ

ប្រសើ):

class Token

{

public Token(string name)

{

}

}

ហៅ Base Class Constructor

class constructor ត្រូវតែហៅវាជាមូលដ្ឋាន class constructor។ អ្នកតែងតែប្រើពាក្សគន្លឹះ base ដើម្បីហៅ base class constructor ។ មានន័យមិនច្បាស់លាស់ក្នុងពេលដែលប្រើពាក្សគន្លឹះ base ពីព្រោះ class មួយអាចមានយ៉ាងតិច base class មួយ ។  ឧទាហរណ៍ទីនេះមាន:

class IdentifierToken : Token

{

}

ប្រសិនបើអ្នកមិនច្បាស់លាស់ហៅ base class មួយនៅក្នុង class constructor ពេល compiler នឹងព្យាយាមហៅ base class នៃ default constructor ។ ឧទាហរណ៍ compiler និងសរសេរឡើងវិញដូចនេះ:

class Token

{

public Token(string name)

{

}

}

​សរសេរ code ឡើងវិញក្លាយដូចនេះ:

class Token : System.Object

{

public Token(string name)

{

}

}

ការធ្វើនេះព្រោះ System.Object មិនមាន public default constructor ។ ទោះបីជាគ្រប់ classes ទាំងអស់មាន public default constructor ក្នុងករណីនេះមិនភ្លេចហៅ base class constructor នឹងមានលទ្ធផលចេញ compile-time error ។ ឧទាហរណ៍:

class IdentifierToken : Token

{

public IdentifierToken(string name)

: base(name) // calls Token(name)

{

}

}

3. ការបង្កើត Interface

ដើម្បីប្រកាស declare interface មួយអ្នកប្រើពាក្យ interface ជំនួស ជំនួសអោយ class ឬពាក្យគន្លឹះ struct ។ នៅខាងក្នុង interface អ្នកប្រកាស declare methods បានពិតប្រាកដ៏ក្នុង class ឬ struct ដែលអ្នកមិនអនុញ្ញាត ផ្លាស់ប្តូរលក្ខណ: (គ្មាន public, private ឬ access) ហើយអ្នកប្តូរ method ជាមួយសញ្ញា semicolon ។ ឧទាហរណ៍:

int CompareTo(object obj)

{

// return 0 if this instance is equal to obj

// return < 0 if this instance is less than obj

// return > 0 if this instance is greater than obj

}

ការអនុវត្តន៍ Interface

ដើម្បីអនុវត្ត interface មួយអ្នកប្រកាស declare class មួយ (ឬ struct មួយ) ដែលទទួលពី interface និងការអនុវត្តន៍គ្រប់ interface ទាំង

អស់នៃ methods ។ ឧទាហរណ៍:

interface IToken

{

string Name();

}

ធ្វើការជាមួយប្រព័ន្ធ inheritance hierarchy

1. ចាប់ផ្តើមចូលក្នុង Microsoft Visual Studio .NET ។

2. បើក CSharp project ដែលមានទីតាំងកក្នុង \Microsoft Press\Visual C# Step by Step\Chapter 12\CSharp folder ដែលមានក្នុង My Documents folder របស់អ្នក ។

3. បើកក្នុងប្រភពដើម SourceFile.cs ក្នុង code pane ។  SourceFile class ផ្ទុក private array field:

interface IToken

{

}

class DefaultTokenImpl

{

}

class IdentifierToken : DefaultTokenImpl , IToken

{

}

ក្នុង SourceFile class ដែលផ្ទុកក្នុង public method ដែលហៅថា Accept ។ វិធី Accept method គឺជាប្រភេទ parameter តែមួយគត់ ItokenVisitor ។ ហៅ Accept methods:

public void Accept(ITokenVisitor visitor)

{

foreach (IVisitableToken token in tokens)

{

token.Accept(visitor);

}

}

4. បើកប្រភព file IVisitableToken.cs នៅក្នុង Code pane ។ IVisitableToken interface ទទួលពី interfaces ពីរផ្សេងទៀតគឺ IVisitable interface និង IToken interface:

interface IVisitableToken : IVisitable, IToken

{

}

5. បើកប្រភព file IVisitable.cs នៅក្នុង Code pane ។ IVisitable interface ប្រកាស declare Accept method ទោលមួយ:

void Process(Itoken iTok)

{

}

ដែល object នីមួយៗនៅក្នុង array យកចេញពីក្នុង SourceFile class ឆ្លងកាត់ IVisitableToken interface ។

6.​បើកក្នុងប្រភព SourceFile.cs ក្នុង Code pane ហើយរកមើលទី តាំង IdentifierToken class ។ ក្នុង IdentifierToken class ទទួល ពី DefaultTokenImpl និង IVisitableToken interface ។ វាអនុវត្ត Accept method ដូចខាងក្រោមនេះ:

void IVisitable.Accept(ITokenVisitor visitor)

{

visitor.VisitIdentifier(ToString());

}

7. បើក ITokenVisitor.cs នៅក្នុង Code pane ។ នៅក្នុង ITokenVisitor interface ផ្ទុក method មួយសំរាប់ប្រភេទនីមួយៗ។ ឧទាហរណ៍:

class MyVisitor : ITokenVisitor

{

public void VisitIdentifier(string token)

{

}

public void VisitKeyword(string token)

{

}

static void Main()

{

SourceFile source = new SourceFile();

MyVisitor visitor = new MyVisitor();

source.Accept(visitor);

}

}

នៅក្នុងលំហាត់ខាងក្រោមនេះ អ្នកនឹងបង្កើត ColorSyntaxVisitor មួយដែលបង្ហាញប្រភព file នៅក្នុងប្រអប់ text color syntax (ឧទាហរណ៍ នៅក្នុងពាក្យគន្លឹះ blue) ។

សរសេរ Color Syntax Visitor class

1.នៅក្នុង Solution Explorer ចុចពីរដង double-click លើ Form1.cs ដើម្បីមើល Color Syntax form ក្នុងសន្លឹក Designer View ។
a

2. បើកក្នុងប្រភព Form1.cs ក្នុង Code pane និងទីតាំងមានពីរ private fields ដែលហៅថា codeText និង Open ដែលបង្ហាញខាង ក្រោមនេះ ។

private System.Windows.Forms.RichTextBox codeText; private System.Windows.Forms.Button Open;

មានពីរ fields ដែលអនុវត្តប្រអប់ text និងប៊ូតុងអ្នកមានទើបតែឃើញ

3. នៅក្នុង Code pane ទីតាំង Form1.Open_Click method ។

method នេះគឺត្រូវបានហៅថាប៊ូតុង Open នៅពេលចុចលើវា ។ អ្នក អនុវត្ត method នេះក្នុងគោល មើលនៅក្នុងប្រអប់ text ។ ប្តូរ Open_Click method ដែលបង្ហាញច្បាស់លាស់ដូចខាងក្រោមនេះ:

private void Open_Click(object sender, System.EventArgs e)

SourceFile source = new SourceFile();

ColorSyntaxVisitor visitor = new ColorSyntaxVisitor(codeText);

source.Accept(visitor);

}

4. បើកប្រភព file ColorSyntaxVisitor.cs នៅក្នុង Code pane ។

5. នៅក្នុង Code pane អនុវត្តសរសេរ method ក្នុង ColorSyntaxVisitor class ដែលបង្ហាញច្បាស់ដូចខាងក្រោមនេះ:

private void Write(string token, Color color)

{

target.AppendText(token);

target.Select(index, index +token.Length);

index += token.Length;

target.SelectionColor = color;

}

6. នៅក្នុង Code pane អនុវត្តវិធីដែលនៅសេសសល់ methods នៃ ColorSyntaxVisitor class ។ ប្រើ Color.Blue សំរាប់ពាក្យគន្លឹះ Color.Green សំរាប់ StringLiterals និង Color.Black សំរាប់វិធីផ្សេង ទៀត:

void ITokenVisitor.VisitComment(string token)

{

Write(token, Color.Black);

}

void ITokenVisitor.VisitIdentifier(string token)

{

Write(token, Color.Black);

}

void ITokenVisitor.VisitKeyword(string token)

{

Write(token, Color.Blue);

}

void ITokenVisitor.VisitOperator(string token)

{

Write(token, Color.Black);

}

void ITokenVisitor.VisitPunctuator(string token)

{

Write(token, Color.Black);

}

void ITokenVisitor.VisitStringLiteral(string token)

{

Write(token, Color.Green);

}

void ITokenVisitor.VisitWhitespace(string token)

{

Write(token, Color.Black);

}

7. នៅលើ Build menu ចុចលើ Build Solution ។ កែតំរូវ errors ផ្សេងនិង rebuild ឡើងវិញប្រសិនបើចាំបាច់ ។

8. នៅលើ Debug menu ចុចលើ Start Without Debugging ។ Color Syntax form បង្ហាញចេញ ។

9. នៅលើ form ចុចលើ Open ។ code ត្រូវបានបង្ហាញក្នុងប្រអប់ text box ជាមួយពាក្យគន្លឹះ blue និង string literals ក្នុង green​ ។
a10. បិទ form អ្នកត្រឡប់ទៅក្នុង Visual Studio .NET ។

ការបង្កើតដ្យាក្រាម Class Diagram
a

ការជាមួយ Multiple Interface

នៅតែអនុវត្តវិធី methods ទាំងអស់ដែលវាទទួលពីក្នុង interfaces ។ abstract class មួយនិង sealed class ទាំងពីរខាងក្រោមនេះមានតួនាទីដូច ជា class មួយ ។ interface មួយគឺមិនអាចអនុញ្ញាតអោយទទួលប្រភេទ class ខុសគ្នា (ដែលនឹងណែនាំការអនុវត្តក្នុង interface) ។

Syntax

ប្រសិនបើ interface, struct ឬ class ទទួលពី interface មួយឬ

ច្រើនជាង interfaces ត្រូវបានសរសេរដោយសញ្ញាក្បៀស ។ ប្រសិនបើ class មួយមានមូលដ្ឋានលើ class មួយទៀត ឧទាហរណ៍:

class IdentifierToken : DefaultTokenImpl, IToken, IVisitable

{

}

ការអនុវត្តន៍ Interface ជាក់ស្តែង

មធ្យោបាយក្នុងការអនុវត្តន៍ struct ឬ class អាចអនុវត្ត interface method ។ នៅក្នុងការឆ្លាស់គ្នា ឈ្មោះវិធី method នេះការអនុវត្តន៍ជាក់ស្តែង មានគុណភាពជាមួយឈ្មោះនៃ interface និងគ្មានការអនុញ្ញាតផ្លាស់ប្តូរ ។ ឧទាហរណ៍ ឧបមាថា IVisitable interface មើលដូចខាងក្រោមនេះ:

interface IVisitable

{

void Accept(IVisitor visitor);

}

អ្នកអាចអនុវត្ត IVisitable interface ដូចនេះ:

public void Accept(ITokenVisitor visitor)

{

foreach (IVisitableToken token in tokens)

{

token.Accept(visitor);

}

}

នេះដែលហៅថាការអនុវត្តន៍ Explicit Interface Implementation (EII) ។ ដែលវិធី EII method ទទួលបានលទ្ធផលដែលបានពីការអនុវត្តន៍ struct ឬ class ។ ឧទាហរណ៍:

IdentifierToken token = new IdentifierToken(“token”);

token.Accept(visitor); //compile-time error: not accessible

ទោះបីជាវិធី method ដែលហៅឆ្លងឈ្មោះ interface ជាក់ស្តែងដែល ប្រើ cast មួយ ឧទាហរណ៍:

IdentifierToken token = new IdentifierToken(“token”);

((IVisitable)token).Accept(visitor); // okay

វិធី EII method ត្រូវបានប្រើយ៉ាងហោចណាស់មានពីរហេតុផល ទីមួយវិធី EII methods បង្កើតព្រឹត្តិការណ៍រវាង interface មួយដែលប្រកាស declares ពីរបៀបប្រើ object មួយ (ប្រភេទមានសារ:ប្រយោជន៍) និង class មួយដែលប្រកាស declare តើត្រូវបង្កើតនិងអនុវត្តបែបណា? ពីព្រោះវិធី EII methods គឺជាលទ្ធផលពី private ទៅ class មធ្យោបាយមួយគត់នេះដែល ហៅមើល object ឆ្លងកាត់ការប្រើ interface ។ ទីពីរ EII method អាច ដោះស្រាយបញ្ហាដោយមាន សក្តានុពលកាលណាឈ្មោះវិធីមួយ method មិន ចុះសំរុងគ្នាមាន interfaces ជាច្រើន ។ ឧទាហរណ៍ សន្មត់ថា IToken និង IVisitable interface ទាំងពីរនេះផ្ទុកក្នុងវិធី method ដែលហៅថា ToString:

interface IToken

{

string ToString();

}

interface IVisitable

{

string ToString();

}

ទោះជាអ្នកចង់ឬមិនចង់ ការអនុវត្តន័ប្រកាស class declares ខាង

ក្រោមនៃ ToString ដែលជាការអនុវត្តន៍នៃវិធីទាំងពីរខាងលើ:

class IdentifierToken : IToken, IVisitable

{

public string ToString()

{

}

}

វិធី EII ផ្តល់់មធ្យោបាយមួយដើម្បីបង្កើតការអនុវត្តន៍ខុសគ្នានៃ ToString ដែលមានមួយក្នុងចំណោមវិធី interface method មួយ ។ ឧទាហរណ៍:

class IdentifierToken : IToken, IVisitable

{

string IToken.ToString()

{

}

string IVisitable.ToString()

{

}

}

សង្ខេបជំពូកទី ១២

ប្រធានបទ

ការអនុវត្តន៍

បង្កើត class ពី base class  ប្រកាស Declare ឈ្មោះ class ថ្មីបន្ទាប់ពី colon និងឈ្មោះនៃ base class ។ ឧទាហរណ៍:class Derived : Base

{

}

ហៅ base class  អនុវត្ត constructor parameter list មុនពេលបង្កើត class constructor. ឧទាហរណ៍:class Derived : Base

{

public Derived(int x) : Base(x)

{

}

}

ប្រកាស Declare virtual method  ប្រើពាក្យគន្លឹះ virtual កាលណា ប្រកាស method ។ ឧទាហរណ៍:class Mammal

{

public virtual void Breathe()

{

}

}

ប្រកាស Declare interface  ប្រើពាក្យគន្លឹះ interface ឧទាហរណ៍:interface IDemo

{

string Name();

string Description();

}

អនុវត្ត interface  ប្រកាស Declare class មួយដែលប្រើ syntax ដូចគ្នាសំរាប់ទទួលដូចជា

Inheritance រួចហើយអនុវត្តគ្រប់មុន ងារទាំងអស់នៃ interface ឧទាហរណ៍

class Test : IDemo

{

public string IDemo.Name()

{

}

public string IDemo.Description()

{

}

}