سؤال

أحاول تنفيذ Stack في Java (باستخدام واجهة القائمة: قائمة الواجهة).

أريد تنفيذه بطريقتين مختلفتين:باستخدام التركيب والميراث.

بالنسبة للميراث، لدي حتى الآن:

 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;

 public class StackInheritance implements List {
      //implement list methods
 }

بالنسبة للتكوين عندي:

 import java.util.List;

 public abstract class StackComposition implements List {
     // implement some standard methods
 }

 public class StackViaList extends StackComposition {
     // implement methods that have not been implemented in the abstract
     // class
 }

أنا في حيرة من أمري إلى أين أذهب من هنا.لم أستخدم واجهة من قبل مطلقًا، لذا هل من المفترض أن أستخدم أساليب القائمة "لتقليد" المكدس، باستخدام Array أو ArrayList على سبيل المثال؟

أيضًا، بالنسبة للتكوين، لا أفهم ما هي الأساليب التي يجب أن تدخل في StackComposition وما الذي يجب أن تدخل في StackViaList.بين عدم فهم الواجهات بشكل كامل وكذلك الميراث والتكوين، أنا ضائع بعض الشيء.لا يبدو أنني أستطيع "فهم الأمر" بعد ...

سيكون موضع تقدير أي مساعدة، وذلك بفضل!

هل كانت مفيدة؟

المحلول

لتكوينها، ويجب على الطبقة كومة ديك قائمة، وليس تنفيذ أو توسيع فئة على أساس قائمة. الإرث هو "هو" العلاقة، في حين تكوين هو "لديه" علاقة.

وعلى سبيل المثال:

public class StackWithComposition
{
    // StackWithComposition HAS A List (rather than IS A List)
    private List myList = new ArrayList();

    public void push(object item)
    {
        // add item to myList, etc.
    }

    public object pop()
    {
        // return item at top (or end) of myList
    }

    // etc.
}

ملاحظة ان كنت تريد على الارجح الى جعل هذه الطبقة العامة، بدلا من التعامل مع الأشياء الخام، ولكن هذا سيكون على هذه الفكرة.

في هذه الحالة، فإن الحل القائم على تكوين وربما الأفضل على حل يستند إلى الميراث. عند يرث من فئة / واجهة، يجب عليك أن تسأل نفسك، هو كومة من القائمة؟ يجب أن معظم الأكوام لا توفر للمستخدم الوصول إلى جميع الطرق قائمة الخام، لذلك فمن الأفضل لإخفاء الوجه الذي كنت تستخدم قائمة كما بنية البيانات الداخلية. باستخدام قائمة تتألف يسمح لك لإخفاء تماما حقيقة أن كنت تستخدم قائمة مثل البنية الداخلية.

نصائح أخرى

لا أعتقد أن هذا سؤال حقيقي.هذا هو السؤال "هل يمكنك القيام بواجباتي المنزلية بالنسبة لي".

الأسئلة الأكثر أهمية ستكون:

  • ما الفرق بين الميراث والتركيب؟
  • ما هي مزايا/عيوب تنفيذ المكدس مع كل منها؟
  • ما هو المكدس؟

أعطى آندي إجابات جيدة على الثلاثة.

لسوء الحظ، يبدو أن مدرس الملصق الأصلي لا يفهم المفاهيم جيدًا بنفسه، نظرًا لأن المهمة غير منطقية.الفئة التي تنفذ java.util.List ليست مكدسًا، أو بالأحرى، ليس من الآمن استخدامها كمكدس، لأنها تتطلب أن تكون العمليات غير الآمنة للمكدس عامة.المكدس عبارة عن واجهة أكثر تقييدًا من القائمة.

لا عجب أن الملصق الأصلي مشوش.

لديك المفاهيم رأسا على عقب.

ميراث, ، كما تقول الكلمة عندما "تأخذ" الوظيفة من كائن موجود.يُعرف هذا بالعلاقة IS-A.على سبيل المثال شاحنة هو عربة.

في عينتك الأولى، لا يعتبر ذلك وراثة، لأنك لا تأخذ أي شيء من القائمة.في عينتك، أنت تقوم "بتنفيذ" تلك القائمة وليس "توسيعها".

تعبير هو عندما تقوم ببناء كائن باستخدام الآخرين (أنت تجمع بين الكائنات).يُعرف هذا بالعلاقة HAS-A.على سبيل المثال شاحنة هاس-أ عجلة (ولكنها ليست عجلة).في عينتك أنت "تمتد" (ترث) من كائن آخر

أخيراً واجهه المستخدم في OOP هو "العقد" الذي يلتزم الكائن بالوفاء به.ما هي الوظائف أو الرسائل التي سيستجيب لها الكائن.

في Java، تعد "الواجهة" أيضًا قطعة أثرية حيث يتم تحديد الأساليب التي سيستجيب بها الكائن.

لذلك، بالنسبة للمكدس، يجب عليك تحديد الطرق التي يمتلكها المكدس (الواجهة)

public interface Stack {
     public void push( Object o );
     public Object pop();
}

ثم باستخدام ميراث يمكنك إنشاء تطبيق المكدس.للقيام بذلك، سيتعين عليك توسيع (أو وراثة) الوظيفة من فئة أخرى.لنفترض أن ArrayList

 /**
  * Sample stack implementation using inheritance
  */
public class ArrayListStack extends ArrayList implements Stack {
// you use the keyword extends because you're inheriting from ArrayList
// and the keyword implements because you claim to respond to push and pop methods.

     public void push( Object o ) {
          this.add( o ); // add inherited from ArrayList
     }
     public Object pop() {
         return this.remove( this.size() -1 ); // remove inherited from ArrayList
     }
}

نظرًا لأنك "ترث" من ArrayList، فإن معظم ما تحتاجه موجود بالفعل.لكن هل يمثل هذا علاقة IS-A؟هل صحيح أن Stack IS-An ArrayList دائمًا؟

لتنفيذ المكدس باستخدام تعبير عليك أن "تجمع" كائنك مع كائن آخر.

  /**
   * Sample stack implementation using composition
   */ 
 public class ComposedStack  implements Stack {
      // you didn't extend anything here

      // But you'll need another object to help you 
      // to do the work.
      private ArrayList holder = .... // Should be declared as List holder = ....


    public void push( Object o ) {
         this.holder.add( o );
    }

    public Object pop() {
        return this.holder.remove( this.holder.size() -1 );
    }
 }

التنفيذ مشابه جدًا، فأنت تستخدم طريقتي "إضافة" و"إزالة" من ArrayList

الفرق هو في الحالة الأولى باستخدام ميراث أنت لا تستخدم هاتين الطريقتين فحسب، بل تقوم بربط الكائن الخاص بك بالكامل بقائمة ArrayList نفسها ( لأنك ورثت أيضًا جميع الطرق الأخرى، وسمة ArrayList )

عندما تستخدم تعبير, ، لا تقوم بربط كائنك بقائمة المصفوفات (أو أن الاقتران منخفض، وهو أمر جيد) أنت ببساطة تستخدم كائنًا آخر لمساعدتك في إنجاز العمل.في هذه الحالة كانت قائمة ArrayList.

من الخارج (باستخدام التركيب)، لا ترى أن هناك ArrayList بالداخل، وهذه معلومات مخفية.لا يرى المستخدم (العميل) لفصلك سوى طريقتين متاحتين هما "الدفع" و"البوب" ولا يوجد شيء آخر يمكن القيام به مع فصلك.يبدو وكأنه مكدس "حقيقي".

من خلال الميراث (باستخدام الكلمة الأساسية الممتدة)، يرى عميل الفصل أيضًا جميع الأساليب من ArrayList على الرغم من أنك قد ترغب في استخدام البوب ​​والدفع فقط، فلا شيء يمنع العميل من استخدام "removeRange" على سبيل المثال.

خاتمة:يعد فهم الاختلافات بين العلاقات is-a و has-a أمرًا ضروريًا لتقنية OO.اتمنى ان يساعدك هذا.

class stack
{

    int n,item,top;
    public stack()
    {
        n=7;
        top=-1;
    }}
    class student extends stack
    {
    int [] stk=new int[4];
    public void insert(int a)
    {
        if(top>=n-1)
        System.out.println("over flow");
        else
        {
            top++;
            stk[top]=a;
        }   
    }
        public void deletestk()
    {
        if(top<0)
            System.out.println("under flow");
            else
            {
                item=stk[top];
                top--;
                    System.out.println("deleted item are"+item);
            }
    }
        public void destroy()
    {
        if(top<0)
            System.out.println("under flow");
            else
            {

            top=-1;
    }
    }
    public void view()
    {
        int i;
        i=top;
        while(i>=0)
        {
                System.out.println(stk[i]);
                i--;
        }
    }   

    }
    class stackfloat extends stack
    {

        float [] stk=new float[6];
    }
    class stkstring extends stack
    {
        String [] stk=new String[5];
    }
    class stackmain
{
    public static void main(String arg[])
    {
        stack ob=new stack();
        student obj=new student();
            obj.deletestk();
        obj.insert(5);
            obj.insert(6);
                obj.insert(64);
                    obj.insert(45);
                        obj.insert(3);
                        obj.view();
                        obj.deletestk();
                        obj.view();
                        obj.destroy();
                        obj.view();



    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top