Soru Polimorfizmin gerçek önemi (kullanımı) nedir


Ben OOP'a yeniyim. Her ne kadar polimorfizmin ne olduğunu anladım, ama bunun gerçek kullanımını alamıyorum. Farklı isimle işlevlerim olabilir. Başvurumda neden polimorfizm uygulamaya çalışmalıyım?


25
2018-01-17 05:04


Menşei


Şuna baksana: stackoverflow.com/questions/409969/... - Zaki
Bu soruya cevap vermeye çalışıyorum. stackoverflow.com/questions/5854581/polymorphism-in-c/... - Bu, polimorfizm için C ++ desteğine odaklansa da, diğer dillerin belirtilen özelliklerin bir alt veya süper kümesi olabilir. Bence konsepti iyi bir şekilde kapsıyor olsa da ... umarım yardımcı olur. - Tony Delroy


Cevaplar:


Klasik cevap: Bir temel sınıf düşünün Shape. Bir ortaya çıkarır GetArea yöntem. Bir düşünün Square sınıf ve bir Rectangle sınıf ve Circle sınıf. Ayrı oluşturmak yerine GetSquareArea, GetRectangleArea ve GetCircleArea yöntemleri, türetilmiş sınıfların her birinde sadece bir yöntem uygulamak. Hangi kesin alt sınıfı bilmeniz gerekmiyor Shape kullanıyorsun, sadece ara GetArea ve sonuç olarak, hangi beton tipinden bağımsız olursanız olun.

Bu koda bir göz atın:

#include <iostream>
using namespace std;

class Shape
{
public:
  virtual float GetArea() = 0;
};

class Rectangle : public Shape
{
public:
  Rectangle(float a) { this->a = a; }
  float GetArea() { return a * a; }
private:
  float a;
};

class Circle : public Shape
{
public:
  Circle(float r) { this->r = r; }
  float GetArea() { return 3.14f * r * r; }
private:
  float r;
};

int main()
{
  Shape *a = new Circle(1.0f);
  Shape *b = new Rectangle(1.0f);

  cout << a->GetArea() << endl;
  cout << b->GetArea() << endl;
}

Burada dikkat edilmesi gereken önemli bir nokta - kullandığınız sınıfın türünü bilmek zorunda değilsiniz, sadece taban tipi ve doğru sonucu alacaksınız. Bu daha karmaşık sistemlerde de çok kullanışlıdır.

İyi eğlenceler!


21
2018-01-17 05:09



Dikdörtgen / Çember, doğal olarak ortaya çıkan klasik "elips problemi" nedeniyle zayıf bir örnek olduğunu düşünüyorum. Genişlik ve yüksekliği ayarlayabileceğiniz bir dikdörtgen sınıfınız olduğunu, daha sonra aynı anda genişlik ve yüksekliği ayarlayan dikdörtgenden uzanan bir kare sınıfı olduğunu varsayalım. Sonra rect.Width * = 2; rect.Height * = 2; aslında size 4x uzunlukları verir. - Warty
Liskov İkame Prensibi için bu aramayı daha çok okumak isteyen herkes için @Warty. - Laurynas Lazauskas


Şimdiye kadar iki tam sayı eklediniz mi? +ve sonra daha sonra bir kayan nokta sayısına bir tamsayı ekledi +?

Hiç giriş yaptın mı x.toString() bir şeyleri ayıklamanıza yardımcı olmak için?

Muhtemelen polimorfizmi takdir ediyorsun, sadece ismi bilmeden.


16
2018-01-17 05:55





Tam olarak yazılmış bir dilde, farklı türden nesnelerin bir listesini / koleksiyonunu / dizisini elde etmek için polimorfizm önemlidir. Bunun nedeni, listelerin / dizilerin yalnızca doğru türdeki nesneleri içerecek şekilde yazılmalarıdır.

Örneğin, şunları elde ettik:

// the following is pseudocode M'kay:
class apple;
class banana;
class kitchenKnife;

apple foo;
banana bar;
kitchenKnife bat;

apple *shoppingList = [foo, bar, bat]; // this is illegal because bar and bat is
                                       // not of type apple.

Bunu çözmek için:

class groceries;
class apple inherits groceries;
class banana inherits groceries;
class kitchenKnife inherits groceries;

apple foo;
banana bar;
kitchenKnife bat;

groceries *shoppingList = [foo, bar, bat]; // this is OK

Ayrıca, eşya listesinin işlenmesini daha kolay hale getirir. Örneğin, tüm yiyecekler yöntemi uygular. price()Bunu işlemek kolaydır:

int total = 0;
foreach (item in shoppingList) {
    total += item.price();
}

Bu iki özellik, polimorfizmin yaptıklarının özüdür.


7
2018-01-17 05:19





Polimorfizmin avantajı, istemci kodunun, bir yöntemin gerçek uygulamasına önem vermemesidir. Aşağıdaki örneğe bakın. Burada CarBuilder, ProduceCar () hakkında bir şey bilmiyor. Bir araba listesi (CarsToProduceList) verildiğinde, gerekli tüm araçları üretecek.

class CarBase
{
    public virtual void ProduceCar()
    {
        Console.WriteLine("don't know how to produce");
    }
}

class CarToyota : CarBase
{
    public override void ProduceCar()
    {
        Console.WriteLine("Producing Toyota Car ");
    }
}

class CarBmw : CarBase
{
    public override void ProduceCar()
    {
        Console.WriteLine("Producing Bmw Car");
    }
}

class CarUnknown : CarBase { }

class CarBuilder
{
    public List<CarBase> CarsToProduceList { get; set; }

    public void ProduceCars()
    {
        if (null != CarsToProduceList)
        {
            foreach (CarBase car in CarsToProduceList)
            {
                car.ProduceCar();// doesn't know how to produce
            }
        }

    }
}

class Program
{
    static void Main(string[] args)
    {
        CarBuilder carbuilder = new CarBuilder();
        carbuilder.CarsToProduceList = new List<CarBase>() { new CarBmw(), new CarToyota(), new CarUnknown() };            
        carbuilder.ProduceCars();
    }
}

5
2018-02-25 09:51





Polimorfizm, Nesne Yönelimli Programlamanın temelidir. Bir nesnenin başka bir proje olabileceği anlamına gelir. Öyleyse nesne üzerinde nasıl bir şey olabilir, takip etmek mümkün

  1. miras
  2. Ana Sınıf davranışını geçersiz kılma / uygulama
  3. Çalışma zamanı nesne bağlama

Bunun en önemli avantajlarından biri anahtar uygulamalarıdır. Veritabanına konuşması gereken bir uygulamayı kodladığınızı söyleyelim. Ve sizin için bu veritabanı işlemini yapan bir sınıf tanımlamanız ve Ekle, Sil, Değiştir gibi belirli işlemleri gerçekleştirmesi beklenir. Veritabanının birçok şekilde uygulanabileceğini biliyorsunuz, dosya sistemiyle veya MySQL gibi bir RDBM sunucusuyla konuşuyor olabilirsiniz. Böylece programcı olarak kullanabileceğiniz bir arabirim tanımlayabilirsiniz.

public interface DBOperation {
    public void addEmployee(Employee newEmployee);
    public void modifyEmployee(int id, Employee newInfo);
    public void deleteEmployee(int id);
}

Şimdi birden fazla uygulamanız olabilir, diyebiliriz ki, RDBMS ve diğer dosya sistemi için bir tane var.

public class DBOperation_RDBMS implements DBOperation
    // implements DBOperation above stating that you intend to implement all
    // methods in DBOperation
    public void addEmployee(Employee newEmployee) {
          // here I would get JDBC (Java's Interface to RDBMS) handle
          // add an entry into database table.
    }
    public void modifyEmployee(int id, Employee newInfo) {
          // here I use JDBC handle to modify employee, and id to index to employee
    }
    public void deleteEmployee(int id) {
          // here I would use JDBC handle to delete an entry
    }
}

Dosya sistemi veritabanı uygulaması var

public class DBOperation_FileSystem implements DBOperation
    public void addEmployee(Employee newEmployee) {
          // here I would Create a file and add a Employee record in to it
    }
    public void modifyEmployee(int id, Employee newInfo) {
          // here I would open file, search for record and change values
    }
    public void deleteEmployee(int id) {
          // here I search entry by id, and delete the record
    }
}

Ana ikisi arasında ana geçişin nasıl olacağını görelim

public class Main {
    public static void main(String[] args) throws Exception {
          Employee emp = new Employee();
          ... set employee information

          DBOperation dboper = null;
          // declare your db operation object, not there is no instance
          // associated with it

          if(args[0].equals("use_rdbms")) {
               dboper = new DBOperation_RDBMS();
               // here conditionally, i.e when first argument to program is
               // use_rdbms, we instantiate RDBM implementation and associate
               // with variable dboper, which delcared as DBOperation.
               // this is where runtime binding of polymorphism kicks in
               // JVM is allowing this assignment because DBOperation_RDBMS
               // has a "is a" relationship with DBOperation.
          } else if(args[0].equals("use_fs")) {
               dboper = new DBOperation_FileSystem(); 
               // similarly here conditionally we assign a different instance.
          } else {
               throw new RuntimeException("Dont know which implemnation to use");
          }

          dboper.addEmployee(emp);
          // now dboper is refering to one of the implementation 
          // based on the if conditions above
          // by this point JVM knows dboper variable is associated with 
          // 'a' implemenation, and it will call appropriate method              
    }
}

Polimorfizm kavramını pek çok yerde kullanabilirsiniz, bir praticle örneği şöyle olacaktır: Resim düzenleyici yazmanıza izin verir ve jpg, tif, png vb. Görüntülerin tümünü desteklemeniz gerekir. Böylece uygulamanız bir arayüz ve iş tanımlayacaktır. doğrudan üzerinde. Ve jpg, tif, pgn vb. İçin çeşitli uygulamaların bazı çalışma zamanı bağlanmalarına sahip olursunuz.

Bir diğer önemli kullanım ise, eğer java kullanıyorsanız, çoğu zaman Liste arayüzünde çalışacaksınız, böylece ArrayList'i bugün veya uygulama büyüdükçe veya ihtiyaçları değiştikçe başka bir arayüzde kullanabilirsiniz.


4
2018-01-17 05:35



iyi! tam olarak benim cevabımı yukarıda belirttiğim gibi. Doğru işlevlerin dinamik çağrılmasına yardımcı olur. ! - Kapil D


Polimorfizm, nesneleri kullanan kod yazmanıza izin verir. Daha sonra, mevcut kodunuzun hiçbir değişiklik yapmadan kullanabileceği yeni sınıflar oluşturabilirsiniz.

Örneğin, bir işleviniz olduğunu varsayalım Lib2Groc(vehicle) Bir aracı kütüphaneden markete yönlendirir. Araçların sola dönmesini söylemek zorundadır, bu yüzden arayabilir TurnLeft() araç nesnesi üzerinde diğer şeyler arasında. Sonra birisi daha sonra bir hovercraft gibi yeni bir aracı çağırırsa, Lib2Groc hiçbir değişiklik yapılmadan.


1
2018-01-17 05:10





Polimorfizme ihtiyacın yok.

Yapana kadar.

Sonra friggen harika.

Pek çok kez baş edeceğiniz basit cevap:

Birilerinin bir şeyler koleksiyonundan geçmesi gerekiyor. MySpecializedCollectionOfAwesome türünde bir koleksiyon istediklerini varsayalım. Ancak, Awesome List olarak örneklerinizi ele alıyorsunuz. Yani, şimdi, bir MSCOA örneği oluşturmak ve Listenizde sahip olduğunuz her Awesome örneği ile doldurmanız gerekecektir <T>. Popoda büyük ağrı, değil mi?

Eh, bir IEnumerable <Başar> için sordu, onları Awesome MANY koleksiyonlarından birini verebilir. Onları bir dizi (Awesome []) veya bir List (List <Awesome>) ya da Awesome veya ANYTHING ELSE'nin göze çarpan bir koleksiyonunu IEnumerable <T> uygulamasında Başarınızı koruyabilirsiniz.

Polimorfizmin gücü, güvende olmanıza izin verir, ancak bu tür veya bu tür özel olarak işleyen kod ton oluşturmadan, bir çok farklı yoldan bir örnek kullanabilmeniz için yeterince esnek olabilir.


0
2018-01-17 05:15





Sanırım bazen nesneler dinamik olarak adlandırılır. Nesnenin klasik bir şekil içinde bir üçgen, kare vb. Olup olmadığından emin değilsiniz. örnek.

Böylece, tüm bu şeyleri geride bırakmak için, sadece türetilmiş sınıfın işlevini çağırıyoruz ve dinamik sınıfın çağrılacağını varsayıyoruz.

Onun bir sqaure, üçgen veya dikdörtgen olması umurumda değil. Sadece alanı önemsiyorsun. Bu nedenle, geçen dinamik nesneye bağlı olarak getArea yöntemi çağrılacaktır.


0
2018-01-17 05:48