यह एक सामान्य OOP प्रश्न हो सकता है। मैं एक इंटरफ़ेस और एक अमूर्त वर्ग के बीच उनके उपयोग के आधार पर एक सामान्य तुलना करना चाहता था।
जब कोई एक इंटरफ़ेस का उपयोग करना चाहेगा और एक अमूर्त वर्ग का उपयोग कब करना चाहेगा ?
यह एक सामान्य OOP प्रश्न हो सकता है। मैं एक इंटरफ़ेस और एक अमूर्त वर्ग के बीच उनके उपयोग के आधार पर एक सामान्य तुलना करना चाहता था।
जब कोई एक इंटरफ़ेस का उपयोग करना चाहेगा और एक अमूर्त वर्ग का उपयोग कब करना चाहेगा ?
जवाबों:
मैंने उस बारे में एक लेख लिखा है:
सारांश:
जब हम अमूर्त वर्गों के बारे में बात करते हैं तो हम एक वस्तु प्रकार की विशेषताओं को परिभाषित कर रहे हैं; वस्तु क्या है, यह निर्दिष्ट करना ।
जब हम एक इंटरफ़ेस के बारे में बात करते हैं और क्षमताओं को परिभाषित करते हैं जो हम प्रदान करने का वादा करते हैं, तो हम इस बारे में एक अनुबंध स्थापित करने के बारे में बात कर रहे हैं कि ऑब्जेक्ट क्या कर सकता है।
Interfaces do not express something like "a Doberman is a type of dog and every dog can walk" but more like "this thing can walk"
:। धन्यवाद
Use abstract classes and inheritance if you can make the statement “A is a B”. Use interfaces if you can make the statement “A is capable of [doing] as”
एक अमूर्त वर्ग साझा राज्य या कार्यक्षमता हो सकता है। एक इंटरफ़ेस केवल राज्य या कार्यक्षमता प्रदान करने का एक वादा है। एक अच्छा अमूर्त वर्ग कोड की मात्रा को कम कर देगा जिसे फिर से लिखना होगा क्योंकि यह कार्यक्षमता या राज्य साझा किया जा सकता है। इंटरफ़ेस को साझा करने के लिए कोई परिभाषित जानकारी नहीं है
व्यक्तिगत रूप से, मुझे लगभग कभी अमूर्त वर्ग लिखने की आवश्यकता नहीं है।
ज्यादातर बार मैं अमूर्त कक्षाओं को (मिस) उपयोग करते हुए देखता हूं, ऐसा इसलिए है क्योंकि अमूर्त वर्ग के लेखक "टेम्पलेट विधि" पैटर्न का उपयोग कर रहे हैं।
"टेम्पलेट पद्धति" के साथ समस्या यह है कि यह लगभग हमेशा कुछ हद तक फिर से प्रवेश कर जाता है - "व्युत्पन्न" वर्ग अपने आधार वर्ग की "सार" पद्धति के बारे में न केवल जानता है कि यह लागू हो रहा है, बल्कि आधार वर्ग के सार्वजनिक तरीकों के बारे में भी है , भले ही ज्यादातर बार उन्हें कॉल करने की आवश्यकता न हो।
(अत्यधिक सरलीकृत) उदाहरण:
abstract class QuickSorter
{
public void Sort(object[] items)
{
// implementation code that somewhere along the way calls:
bool less = compare(x,y);
// ... more implementation code
}
abstract bool compare(object lhs, object rhs);
}
तो यहाँ, इस वर्ग के लेखक ने एक सामान्य एल्गोरिथ्म लिखा है और लोगों को इसे "स्वयं" हुक प्रदान करके "इसका उपयोग" करने का इरादा है - इस मामले में, एक "तुलना" विधि।
तो इच्छित उपयोग कुछ इस तरह है:
class NameSorter : QuickSorter
{
public bool compare(object lhs, object rhs)
{
// etc.
}
}
इसके साथ समस्या यह है कि आपने दो अवधारणाओं को एक साथ जोड़ दिया है:
उपरोक्त कोड में, सैद्धांतिक रूप से, "तुलना" विधि के लेखक सुपरक्लास "सॉर्ट" पद्धति में फिर से प्रवेश कर सकते हैं ... भले ही व्यवहार में वे कभी ऐसा नहीं करना चाहेंगे या करने की आवश्यकता नहीं होगी।
इस अनावश्यक युग्मन के लिए आप जो मूल्य अदा करते हैं, वह यह है कि सुपरक्लास को बदलना कठिन है, और अधिकांश OO भाषाओं में, इसे रनटाइम में बदलना असंभव है।
वैकल्पिक विधि इसके बजाय "रणनीति" डिजाइन पैटर्न का उपयोग करना है:
interface IComparator
{
bool compare(object lhs, object rhs);
}
class QuickSorter
{
private readonly IComparator comparator;
public QuickSorter(IComparator comparator)
{
this.comparator = comparator;
}
public void Sort(object[] items)
{
// usual code but call comparator.Compare();
}
}
class NameComparator : IComparator
{
bool compare(object lhs, object rhs)
{
// same code as before;
}
}
तो अब ध्यान दें: हमारे पास सभी इंटरफेस हैं, और उन इंटरफेस के ठोस कार्यान्वयन हैं। व्यवहार में, आपको उच्च स्तरीय OO डिज़ाइन करने के लिए वास्तव में किसी और चीज़ की आवश्यकता नहीं है।
"QuickSort" वर्ग और "NameComparator" का उपयोग करके "नामों को छांटने" वाले तथ्य को "छिपाने" के लिए, हम अभी भी कहीं न कहीं एक कारखाना विधि लिख सकते हैं:
ISorter CreateNameSorter()
{
return new QuickSorter(new NameComparator());
}
किसी भी समय आपके पास एक अमूर्त वर्ग है जो आप ऐसा कर सकते हैं ... यहां तक कि जब आधार और व्युत्पन्न वर्ग के बीच एक प्राकृतिक फिर से प्रवेश संबंध होता है, तो यह आमतौर पर उन्हें स्पष्ट करने के लिए भुगतान करता है।
एक अंतिम विचार: ऊपर हमने जो भी किया है वह "क्विकसॉर्ट" फ़ंक्शन और "नेम कॉमपर्सन" फ़ंक्शन का उपयोग करके "NameSorting" फ़ंक्शन की रचना है ... एक कार्यात्मक प्रोग्रामिंग भाषा में, प्रोग्रामिंग की यह शैली और भी स्वाभाविक हो जाती है, कम कोड के साथ।
यदि आप जावा को ओओपी भाषा के रूप में देख रहे हैं,
" इंटरफ़ेस पद्धति कार्यान्वयन प्रदान नहीं करता है " जावा 8 लॉन्च के साथ अब मान्य नहीं है। अब जावा डिफ़ॉल्ट तरीकों के लिए इंटरफ़ेस में कार्यान्वयन प्रदान करता है।
सरल शब्दों में, मैं उपयोग करना चाहूंगा
इंटरफ़ेस: कई असंबंधित वस्तुओं द्वारा एक अनुबंध को लागू करने के लिए। यह " एचएएस ए " क्षमताप्रदान करताहै।
अमूर्त वर्ग: कई संबंधित वस्तुओं के बीच एक ही या अलग व्यवहार को लागू करने के लिए। यह " आईएस ए " संबंधस्थापित करता है ।
Oracle वेबसाइट , वर्ग interface
और abstract
वर्ग के बीच महत्वपूर्ण अंतर प्रदान करती है ।
अमूर्त कक्षाओं का उपयोग करने पर विचार करें यदि:
यदि इंटरफेस का उपयोग करने पर विचार करें :
Serializable
इंटरफ़ेस को लागू कर सकते हैं ।उदाहरण:
सार वर्ग ( एक रिश्ता है)
पाठक एक अमूर्त वर्ग है।
बफ़रड्रेडर एक हैReader
FileReader एक हैReader
FileReader
और BufferedReader
आम उद्देश्य के लिए उपयोग किया जाता है: डेटा पढ़ना, और वे Reader
कक्षा के माध्यम से संबंधित हैं ।
इंटरफ़ेस ( एचए ए क्षमता)
Serializable एक इंटरफ़ेस है।
मान लें कि आपके आवेदन में दो कक्षाएं हैं, जो Serializable
इंटरफ़ेस लागू कर रहे हैं
Employee implements Serializable
Game implements Serializable
यहां आप Serializable
इंटरफ़ेस के माध्यम से कोई संबंध स्थापित नहीं कर सकते हैं Employee
और Game
, जो अलग-अलग उद्देश्य के लिए हैं। दोनों राज्य को सीरियलाइज़ करने में सक्षम हैं और तुलना वहीं समाप्त होती है।
इन पदों पर एक नजर:
मुझे इंटरफ़ेस और अमूर्त वर्ग के बीच अंतर कैसे समझाया जाना चाहिए?
ठीक है, अपने आप को यह "पक्का" कर रहा है - यहाँ यह आम आदमी की शर्तों में है (अगर मुझे गलत लगता है तो मुझे सुधारने के लिए स्वतंत्र महसूस करें) - मुझे पता है कि यह विषय एक दिन का है, लेकिन हो सकता है कि कोई और इसे एक दिन ठोकर खाए ...
अमूर्त कक्षाएं आपको एक खाका बनाने की अनुमति देती हैं, और आपको अतिरिक्त रूप से CONSTRUCT (कार्यान्वयन) गुण और विधियाँ प्रदान करने की अनुमति देती हैं जो आप चाहते हैं कि इसके सभी वंशज इसके अधिकारी हों।
दूसरी ओर एक इंटरफ़ेस केवल आपको यह घोषित करने की अनुमति देता है कि आप सभी वर्गों में मौजूद किसी नाम के साथ गुण और / या विधियाँ चाहते हैं जो इसे लागू करते हैं - लेकिन यह निर्दिष्ट नहीं करता है कि आपको इसे कैसे लागू करना चाहिए। इसके अलावा, एक वर्ग MANY इंटरफेस को लागू कर सकता है, लेकिन केवल एक सार वर्ग का विस्तार कर सकता है। एक इंटरफ़ेस एक उच्च स्तर के वास्तुशिल्प उपकरण से अधिक है (जो डिज़ाइन पैटर्न को समझने के लिए शुरू होने पर स्पष्ट हो जाता है) - एक सार दोनों शिविरों में एक पैर होता है और कुछ गंदे काम भी कर सकता है।
एक का उपयोग दूसरे पर क्यों करें? पूर्व वंशजों की अधिक ठोस परिभाषा के लिए अनुमति देता है - उत्तरार्द्ध अधिक बहुरूपता की अनुमति देता है । यह अंतिम बिंदु अंतिम उपयोगकर्ता / कोडर के लिए महत्वपूर्ण है, जो अपनी आवश्यकताओं के अनुरूप संयोजन I / आकार में AP I (nterface) को लागू करने के लिए इस जानकारी का उपयोग कर सकते हैं।
मुझे लगता है कि यह मेरे लिए "लाइटबल्ब" क्षण था - लेखक के दृष्टिकोण से कम इंटरफेस के बारे में सोचें और बाद में आने वाले किसी भी कोडर से अधिक जो एक परियोजना में कार्यान्वयन जोड़ रहा है, या एक एपीआई का विस्तार कर रहा है।
मेरे दो सेंट:
एक इंटरफ़ेस मूल रूप से एक अनुबंध को परिभाषित करता है, कि किसी भी कार्यान्वयन वर्ग को (इंटरफ़ेस सदस्यों को लागू करने) का पालन करना होगा। इसमें कोई कोड नहीं है।
दूसरी ओर, एक अमूर्त वर्ग में कोड हो सकता है, और सार के रूप में चिह्नित कुछ विधियाँ हो सकती हैं जिन्हें एक अनुगामी वर्ग को लागू करना चाहिए।
मैंने जिन अमूर्त कक्षाओं का उपयोग किया है, वे दुर्लभ स्थितियाँ हैं, जब मेरे पास कुछ डिफ़ॉल्ट कार्यक्षमता होती है, जो कि मूल वर्ग को ओवरराइड करने में दिलचस्प नहीं हो सकती है, यह कहना कि अमूर्त आधार वर्ग है, कि कुछ विशेष वर्गों से विरासत में मिली है।
उदाहरण (एक बहुत ही मौलिक एक!): एक आधार वर्ग कहा जाता है ग्राहक जो की तरह अमूर्त तरीकों है पर विचार करें CalculatePayment()
, CalculateRewardPoints()
और जैसे कुछ गैर सार तरीकों GetName()
, SavePaymentDetails()
।
की तरह विशेष कक्षाओं RegularCustomer
और GoldCustomer
से प्राप्त कर लेंगे Customer
आधार वर्ग और अपने स्वयं के लागू CalculatePayment()
और CalculateRewardPoints()
विधि तर्क है, लेकिन फिर से उपयोग करें GetName()
और SavePaymentDetails()
तरीकों।
आप बच्चे वर्ग को प्रभावित किए बिना एक अमूर्त वर्ग (गैर अमूर्त विधियाँ) के लिए अधिक कार्यक्षमता जोड़ सकते हैं जो पुराने संस्करण का उपयोग कर रहे थे। इंटरफ़ेस को जोड़ने के तरीकों को लागू करने से सभी वर्ग प्रभावित होंगे, क्योंकि उन्हें अब नए जोड़े गए इंटरफ़ेस सदस्यों को लागू करने की आवश्यकता होगी।
सभी सार सदस्यों के साथ एक सार वर्ग एक इंटरफ़ेस के समान होगा।
अगर आपके मन में अवधारणा स्पष्ट है तो क्या करना है, यह बहुत ही सरल बात है।
सार वर्ग व्युत्पन्न किया जा सकता है, जबकि इंटरफेस को लागू किया जा सकता है। दोनों में कुछ अंतर है। जब आप एक सार वर्ग प्राप्त करते हैं, तो व्युत्पन्न वर्ग और आधार वर्ग के बीच का संबंध एक 'संबंध' है। उदाहरण के लिए, एक कुत्ता एक जानवर है, एक भेड़ एक जानवर है जिसका अर्थ है कि एक व्युत्पन्न वर्ग आधार वर्ग से कुछ गुणों को प्राप्त कर रहा है।
जबकि इंटरफेस के कार्यान्वयन के लिए, संबंध "हो सकता है"। उदाहरण के लिए, एक कुत्ता एक जासूसी कुत्ता हो सकता है। एक कुत्ता एक सर्कस कुत्ता हो सकता है। कुत्ता नस्ल का कुत्ता हो सकता है। जिसका मतलब है कि आप कुछ हासिल करने के लिए कुछ तरीकों को लागू करते हैं।
मुझे उम्मीद है कि मैं स्पष्ट हूं।
1.अगर आप कुछ ऐसा बना रहे हैं जो असंबद्ध वर्गों को सामान्य कार्यक्षमता प्रदान करता है, तो इंटरफ़ेस का उपयोग करें।
2.अगर आप उन वस्तुओं के लिए कुछ बना रहे हैं जो पदानुक्रम में निकट से संबंधित हैं, तो एक अमूर्त वर्ग का उपयोग करें।
मैंने एक लेख लिखा था कि अमूर्त वर्ग का उपयोग कब करना है और इंटरफ़ेस का उपयोग कब करना है। "एक IS-A ... और एक CAN-DO ..." के अलावा उनके बीच बहुत अंतर है। मेरे लिए, वे डिब्बाबंद जवाब हैं। मैं उनमें से किसी एक का उपयोग करने के कुछ कारणों का उल्लेख करता हूं। आशा है ये मदद करेगा।
मुझे लगता है कि इसे लगाने का सबसे सरल तरीका निम्नलिखित है:
साझा गुण => सार वर्ग।
साझा कार्यक्षमता => इंटरफ़ेस।
और इसे कम करने के लिए पूरी तरह से ...
सार वर्ग उदाहरण:
public abstract class BaseAnimal
{
public int NumberOfLegs { get; set; }
protected BaseAnimal(int numberOfLegs)
{
NumberOfLegs = numberOfLegs;
}
}
public class Dog : BaseAnimal
{
public Dog() : base(4) { }
}
public class Human : BaseAnimal
{
public Human() : base(2) { }
}
चूंकि जानवरों के पास एक साझा संपत्ति है - इस मामले में पैरों की संख्या - यह एक सार वर्ग बनाने के लिए समझ में आता है जिसमें इस साझा संपत्ति होती है। इससे हम उस संपत्ति पर काम करने वाले सामान्य कोड को भी लिख सकते हैं। उदाहरण के लिए:
public static int CountAllLegs(List<BaseAnimal> animals)
{
int legCount = 0;
foreach (BaseAnimal animal in animals)
{
legCount += animal.NumberOfLegs;
}
return legCount;
}
इंटरफ़ेस उदाहरण:
public interface IMakeSound
{
void MakeSound();
}
public class Car : IMakeSound
{
public void MakeSound() => Console.WriteLine("Vroom!");
}
public class Vuvuzela : IMakeSound
{
public void MakeSound() => Console.WriteLine("VZZZZZZZZZZZZZ!");
}
यहां ध्यान दें कि Vuvuzelas और Cars पूरी तरह से अलग चीजें हैं, लेकिन उन्होंने कार्यक्षमता साझा की है: एक ध्वनि बनाना। इस प्रकार, एक इंटरफ़ेस यहाँ समझ में आता है। इसके अलावा, यह प्रोग्रामर को उन चीजों को समूहित करने की अनुमति देगा IMakeSound
जो इस मामले में एक सामान्य इंटरफ़ेस के तहत एक साथ ध्वनियां बनाते हैं । इस डिजाइन के साथ, आप निम्नलिखित कोड लिख सकते हैं:
List<IMakeSound> soundMakers = new List<ImakeSound>();
soundMakers.Add(new Car());
soundMakers.Add(new Vuvuzela());
soundMakers.Add(new Car());
soundMakers.Add(new Vuvuzela());
soundMakers.Add(new Vuvuzela());
foreach (IMakeSound soundMaker in soundMakers)
{
soundMaker.MakeSound();
}
क्या आप बता सकते हैं कि आउटपुट क्या होगा?
अंत में, आप दोनों को जोड़ सकते हैं।
संयुक्त उदाहरण:
public interface IMakeSound
{
void MakeSound();
}
public abstract class BaseAnimal : IMakeSound
{
public int NumberOfLegs { get; set; }
protected BaseAnimal(int numberOfLegs)
{
NumberOfLegs = numberOfLegs;
}
public abstract void MakeSound();
}
public class Cat : BaseAnimal
{
public Cat() : base(4) { }
public override void MakeSound() => Console.WriteLine("Meow!");
}
public class Human : BaseAnimal
{
public Human() : base(2) { }
public override void MakeSound() => Console.WriteLine("Hello, world!");
}
यहाँ, हम सभी BaseAnimal
को एक ध्वनि बनाने की आवश्यकता है , लेकिन हम इसके कार्यान्वयन को अभी तक नहीं जानते हैं। ऐसे मामले में, हम इंटरफ़ेस कार्यान्वयन को सार कर सकते हैं और इसके उपवर्गों को इसके कार्यान्वयन को सौंप सकते हैं।
एक अंतिम बिंदु, याद रखें कि कैसे अमूर्त वर्ग उदाहरण में हम विभिन्न वस्तुओं के साझा गुणों पर काम करने में सक्षम थे और इंटरफ़ेस उदाहरण में हम विभिन्न वस्तुओं की साझा कार्यक्षमता को लागू करने में सक्षम थे? इस अंतिम उदाहरण में, हम दोनों कर सकते हैं।
इंटरफ़ेस पर एक अमूर्त वर्ग को कब पसंद करें?
अमूर्त वर्ग पर एक इंटरफ़ेस कब पसंद करना है?
कक्षाएं केवल एक आधार वर्ग से विरासत में मिल सकती हैं, इसलिए यदि आप कक्षाओं के एक समूह को बहुरूपता प्रदान करने के लिए अमूर्त कक्षाओं का उपयोग करना चाहते हैं, तो उन्हें उस वर्ग से विरासत में प्राप्त करना होगा। सार वर्ग उन सदस्यों को भी प्रदान कर सकते हैं जो पहले से ही लागू हो चुके हैं। इसलिए, आप एक अमूर्त वर्ग के साथ एक निश्चित मात्रा में समान कार्यक्षमता सुनिश्चित कर सकते हैं, लेकिन इंटरफ़ेस के साथ नहीं कर सकते।
आपके घटकों के लिए बहुरूपता प्रदान करने के लिए एक इंटरफ़ेस या एक सार वर्ग का उपयोग करने के लिए यह तय करने में आपकी सहायता करने के लिए यहां कुछ सिफारिशें दी गई हैं।
से कॉपी किया गया:
http://msdn.microsoft.com/en-us/library/scsyfw1d%28v=vs.71%29.aspx
यदि इनमें से कोई भी कथन आपकी स्थिति पर लागू होता है, तो अमूर्त कक्षाओं का उपयोग करने पर विचार करें :
यदि इन कथनों में से कोई भी आपकी स्थिति पर लागू होता है, तो इंटरफेस का उपयोग करने पर विचार करें :
उत्तर भाषाओं के बीच भिन्न होते हैं। उदाहरण के लिए, जावा में एक वर्ग कई इंटरफेस को लागू (विरासत से) कर सकता है लेकिन केवल एक सार वर्ग से विरासत में मिलता है। इसलिए इंटरफेस आपको अधिक लचीलापन देते हैं। लेकिन C ++ में यह सच नहीं है।
मेरे लिए, मैं कई मामलों में इंटरफेस के साथ जाऊंगा। लेकिन मैं कुछ मामलों में अमूर्त कक्षाएं पसंद करता हूं।
OO सामान्य में कक्षाएं कार्यान्वयन को संदर्भित करती हैं। मैं अमूर्त कक्षाओं का उपयोग करता हूं, जब मैं कुछ कार्यान्वयन विवरणों को मजबूर करना चाहता हूं, तो मैं इंटरफ़ेस के साथ जाता हूं।
बेशक, अमूर्त वर्ग न केवल कार्यान्वयन के लिए बल्कि कई संबंधित वर्गों के बीच कुछ विशिष्ट विवरणों को साझा करने में उपयोगी हैं।
यदि आप कुछ बुनियादी कार्यान्वयन प्रदान करना चाहते हैं तो एक सार वर्ग का उपयोग करें।
जावा में आपको कार्यक्षमता प्रदान करने के लिए एक (सार) वर्ग से विरासत में मिल सकता है और आप कार्यक्षमता सुनिश्चित करने के लिए कई इंटरफेस लागू कर सकते हैं
विशुद्ध रूप से वंशानुक्रम के आधार पर, आप एक ऐसे सार का उपयोग करेंगे जहां आप स्पष्ट रूप से वंशज, अमूर्त रिश्तों (अर्थात पशु-> बिल्ली) को परिभाषित कर रहे हैं और / या आभासी या गैर-सार्वजनिक संपत्तियों के उत्तराधिकार की आवश्यकता है, विशेष रूप से साझा स्थिति (जो इंटरफ़ेक्ट का समर्थन नहीं कर सकते हैं) )।
आपको विरासत पर निर्भरता के माध्यम से रचना (निर्भरता इंजेक्शन के माध्यम से) का प्रयास करना चाहिए, जहां आप कर सकते हैं, और ध्यान दें कि इंटरफेसेस का समर्थन इकाई-परीक्षण, अनुबंधों को अलग करने और (अलग-अलग भाषा) एकाधिक विरासत को एक तरह से करने के लिए किया जा सकता है।
एक दिलचस्प स्थान जहां इंटरफेस अमूर्त कक्षाओं से बेहतर होता है, जब आपको (संबंधित या असंबंधित) वस्तुओं के समूह में अतिरिक्त कार्यक्षमता जोड़ने की आवश्यकता होती है। यदि आप उन्हें एक आधार सार वर्ग नहीं दे सकते हैं (उदाहरण के लिए, वे sealed
पहले से ही एक माता-पिता हैं), तो आप उन्हें इसके बजाय एक डमी (खाली) इंटरफ़ेस दे सकते हैं, और फिर उस इंटरफ़ेस के लिए केवल विस्तार विधियाँ लिख सकते हैं।
यह एक बहुत मुश्किल कॉल करने के लिए हो सकता है ...
एक पॉइंटर जो मैं दे सकता हूं: एक ऑब्जेक्ट कई इंटरफेस को लागू कर सकता है, जबकि एक ऑब्जेक्ट केवल एक बेस क्लास (आधुनिक ओओ भाषा में सी # की तरह प्राप्त कर सकता है, मुझे पता है कि सी ++ के पास कई विरासत हैं - लेकिन क्या यह नहीं है?)
एक अमूर्त वर्ग में कार्यान्वयन हो सकता है।
एक इंटरफ़ेस में कार्यान्वयन नहीं है, यह बस एक तरह के अनुबंध को परिभाषित करता है।
कुछ भाषा-निर्भर अंतर भी हो सकते हैं: उदाहरण के लिए C # में एकाधिक वंशानुक्रम नहीं है, लेकिन एक वर्ग में कई इंटरफेस लागू किए जा सकते हैं।
मूल अंगूठे नियम है: "संज्ञा" के लिए सार वर्ग का उपयोग करें और "क्रिया" इंटरफ़ेस का उपयोग करें
जैसे: car
एक अमूर्त वर्ग है और drive
, हम इसे एक इंटरफ़ेस बना सकते हैं।
drive
कार की कार्यक्षमता को भी रोक सकते हैं - जो कि एक अमूर्त वर्ग है।