Çok Biçimlilik vs Geçersiz Kılma


347

Java açısından, birisi sorduğunda:

polimorfizm nedir?

Misiniz aşırı veya geçersiz kılma kabul edilebilir bir cevap olabilir mi?

Bence bundan daha fazlası var.

Uygulamasız bir yöntemi tanımlayan soyut bir temel sınıfınız varsa ve bu alt sınıfta bu yöntemi tanımladıysanız, bu hala geçersiz kılıyor mu?

Aşırı yüklemenin doğru cevap olmadığını düşünüyorum .


Aşağıdaki cevaplar polimorfizm hakkında çok iyi açıklar. Ama aşırı yüklemenin, aslında aşırı yüklemeye konsantre olan polimorfizm olup olmadığını benim sorum ve cevabımda gerekçelendirmeye çalıştığım bir tür polimorfizm olduğunu söylemek güçlü bir itirazım var. Bu konudaki Digital Gabeg cevabını @ haklı göstermeye çalıştım. Bakınız detaylandırma: Yöntem aşırı yükleme polimorfizm bağlayıcı değil statik / derleme zamanı. Statik bağlamayı polimorfizmle ilişkilendirmek doğru mu?
PraveenKumar Lalasangi

Yanıtlar:


894

Polimorfizmi ifade etmenin en açık yolu soyut bir temel sınıf (veya arabirim)

public abstract class Human{
   ...
   public abstract void goPee();
}

Bu sınıf soyuttur, çünkü goPee()yöntem İnsanlar için tanımlanamaz. Sadece Erkek ve Kadın alt sınıfları için tanımlanabilir. Ayrıca, İnsan soyut bir kavramdır - Ne Erkek ne de Kadın olan bir insan yaratamazsınız. Biri ya da diğeri olmalı.

Dolayısıyla soyut sınıfı kullanarak uygulamayı erteliyoruz.

public class Male extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Stand Up");
    }
}

ve

public class Female extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Sit Down");
    }
}

Şimdi İnsanlarla dolu bir odaya işeyip gitmesini söyleyebiliriz.

public static void main(String[] args){
    ArrayList<Human> group = new ArrayList<Human>();
    group.add(new Male());
    group.add(new Female());
    // ... add more...

    // tell the class to take a pee break
    for (Human person : group) person.goPee();
}

Bunu çalıştırmak aşağıdakileri sağlar:

Stand Up
Sit Down
...

37
@yuudachi. Bir ders verirken bu örneği buldum. Standart “Banka Hesabı” sınıfı, temel sınıfın “soyutluğunu” gerçekten ifade etmemiştir. Diğer kanonik örnek (Hayvan, gürültü yapmak) anlaşılamayacak kadar soyuttu. Çok açık alt sınıfları olan tek bir üs arıyordum. Aslında goPee (), cinsiyetçi ya da basmakalıp olmayan tek örnekti. (sınıfta olmasına rağmen, ayağa kalkmak veya oturmak yerine "soldaki salonu aşağıya
bastım"

100
Bu örnek aynı zamanda biyolojik sistemleri tanımlamak için hiyerarşik bir sistem kullanmanın zorluğunu vurgulamaktadır. Çok genç gibi bazı insanlar hemen hemen her pozisyonda işemekte ve bebeklere kolayca goPee () söyleyememektedir. Bazı insanlar “erkek” veya “dişi” biyolojik etiketlerinin oldukça kötü tanımlandığı intersekslerdir; sosyal anlamlar daha da karmaşıktır. Bir öğretme örneği olarak, modelleme varsayımlarının, idrarını tutamayan veya interseks olan birinin (örneğin, OO programlama öğrencisi) gerçekte insan olmadığı gibi imaları nasıl olumsuz sonuçlara sahip olabileceğini gösterir.
Andrew Dalke

7
"En azından ne erkek ne de kadın olan bir insan yaratamazsın" tezinizi çürütecek en az bir avuç insan düşünebilirim, yine de kodunuz için doğru olsa da ... kötü soyutlama ? ;)
Frank W. Zammetti

2
Ben sadece polimorfizm olduğunu belirtmek önemlidir düşünüyorum çünkü hangi goPee () sürümü sadece çalışma zamanında belirlenebilir. Bu örnek bunu ima etse de, bunun tam olarak neden polimorfizm olduğunu belirtmek güzel. Ayrıca, kardeş sınıfları gerektirmez. Bir ebeveyn-çocuk ilişkisi de olabilir. Ya da tesadüfen aynı işleve sahip tamamen ilgisiz sınıflar bile. Bunun bir örneği .toString () işlevi olabilir. Hangi herhangi bir nesne üzerinde rastgele çağrılabilir, ancak derleyici asla tam olarak hangi tür nesne bilemez.
Tor Valamo

20
@AndrewDalke, biyolojik karmaşıklık üzerine notlar için +1. Ayrıca, goPeegirdi olarak yerçekimi alanı almaz. Küresel duruma bu bağımlılık, birim testini CatheterizedIntersexAstronautzorlaştırır ve alt sınıflamanın her zaman özelliklerin bileşimi için en iyi yöntem olmayabileceğini gösterir.
Mike Samuel

99

Çok biçimlilik , bir sınıf örneğinin miras ağacında, çoğunlukla ata sınıflarından biri olan başka bir sınıfın örneği gibi davranma yeteneğidir. Örneğin, Java'da tüm sınıflar Object öğesinden devralınır. Bu nedenle, Object türünde bir değişken oluşturabilir ve ona herhangi bir sınıfın örneğini atayabilirsiniz.

bir geçersiz kılmabaşka bir sınıftan miras alan bir sınıfta oluşan bir işlev türüdür. Bir geçersiz kılma işlevi, temel sınıftan devralınan bir işlevi "değiştirir", ancak bunu, sınıfının bir örneği polimorfizm yoluyla farklı bir tür gibi davransa bile çağrıldığı şekilde yapar. Önceki örneğe bakarak kendi sınıfınızı tanımlayabilir ve toString () işlevini geçersiz kılabilirsiniz. Bu işlev Object öğesinden devralındığından, bu sınıfın bir örneğini Object-type değişkenine kopyalarsanız da kullanılabilir. Normalde, bir Nesne gibi davranırken sınıfınızda toString () öğesini çağırırsanız, gerçekte tetiklenecek toString sürümü Object'in kendisinde tanımlanan sürümdür. Ancak, işlev bir geçersiz kılma olduğundan, sınıfınızdaki toString () tanımı, sınıf örneği '

Aşırı yükleme , aynı ada, ancak farklı parametrelere sahip birden çok yöntem tanımlama eylemidir. Geçersiz kılma veya polimorfizm ile ilgisi yoktur.


8
Bu eskidir ama Polimorfizm diğer sınıfın kalıtım ağacında olması gerektiği anlamına gelmez. Arabirimlerin miras ağacının bir parçası olduğunu düşünürseniz, ancak arabirimlerin örtülü olarak uygulandığı Go'da değil.
JN

5
Aslında, polimorfizm için hiçbir derse ihtiyacınız yok.
StCredZero

3
Ben bir acemiyim ve eğer yanılıyorsam beni düzeltin, ama aşırı yüklemenin polimorfizmle ilgisi olmadığını söyleyemem. En azından Java'da, polimorfizm uygulamanın arayanın türüne göre seçilmesi ve aşırı yüklenmenin ise parametrelerin türüne göre seçilmesidir, öyle değil mi? İkisi arasındaki benzerliği görmek onu anlamama yardımcı olur.
csjacobs24

9
Yanlış. Ad hoc polymorphismEğer anlatılan budur Overloading bölümü ve bir polimorfizm bir olgu.
Jossie Calderon

1
"Ya geçersiz kılma ya da polimorfizm ile ilgisi yoktur". Bu ifade yanlış.
Shailesh Pratapwar

45

Polimorfizm, ihtiyaca göre farklı işlemler gerçekleştiren birden fazla form anlamına gelir.

Çok biçimlilik iki yolla elde edilebilir, bunlar

  1. Yöntem geçersiz kılma
  2. Yöntem aşırı yükleme

Yöntem aşırı yükleme , aynı yöntem adını kullanarak aynı sınıfta iki veya daha fazla yöntem yazmak anlamına gelir, ancak geçen parametreler farklıdır.

Yöntem geçersiz kılma yöntemi, farklı sınıflarda yöntem adlarını kullandığımız anlamına gelir, yani alt sınıfta üst sınıf yöntemi kullanılır.

Java'da polimorfizme ulaşmak için bir süper sınıf referans değişkeni alt sınıf nesnesini tutabilir.

Polimorfizme ulaşmak için her geliştiricinin projede aynı yöntem adlarını kullanması gerekir.


4
Güzel cevap için +1. Kabul edilen cevap sadece bir tür polimorfizmi açıklar. Bu cevap tamamlandı.
apadana

1
polimorfizm bir paradigmadır (OOP), ancak geçersiz kılma ve aşırı yükleme dil tesisleridir.
威 其 威

Polimorfizm jenerik tip ile de elde edilebilir.
Minh Nghĩa

43

Pseudo-C # / Java'da polimorfizme bir örnek:

class Animal
{
    abstract string MakeNoise ();
}

class Cat : Animal {
    string MakeNoise () {
        return "Meow";
    }
}

class Dog : Animal {
    string MakeNoise () {
        return "Bark";
    }
}

Main () {
   Animal animal = Zoo.GetAnimal ();
   Console.WriteLine (animal.MakeNoise ());
}

Ana işlev hayvanın türünü bilmez ve belirli bir uygulamanın MakeNoise () yöntemindeki davranışına bağlıdır.

Edit: Görünüşe göre Brian yumruk beni dövdü. Komik aynı örneği kullandık. Ancak yukarıdaki kod kavramları netleştirmeye yardımcı olmalıdır.


Çalışma zamanı polimorfizminin bir örneği. Derleme zamanı polimorfizmi yöntem aşırı yüklemesi ve genel tiplerle de mümkündür.
Pete Kirkham

Şekil -> Paralelkenar -> Dikdörtgen -> Kare
mpen

@ yankee2905 Bu durumda, bir sınıf birden çok arabirim uygulayabildiğinden, arabirimleri kullanabileceğinizi düşünüyorum.
Sam003

1
@Zhisheng Ya da soyut ebeveyn sınıfına işemek yöntemi ekliyor musunuz? Başka bir şey uygulamak için arayüzü kullanırdım.
joey rohan

43

Hem geçersiz kılma hem de aşırı yükleme, polimorfizme ulaşmak için kullanılır.

Bir sınıfta, bir veya daha fazla alt sınıfta geçersiz kılınmış bir yönteminiz olabilir . Yöntem, bir nesneyi başlatmak için hangi sınıfın kullanıldığına bağlı olarak farklı şeyler yapar.

    abstract class Beverage {
       boolean isAcceptableTemperature();
    }

    class Coffee extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature > 70;
       }
    }

    class Wine extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature < 10;
       }
    }

Ayrıca, iki veya daha fazla bağımsız değişken kümesi ile aşırı yüklenmiş bir yönteminiz olabilir . Yöntem, iletilen argüman (lar) ın türlerine göre farklı şeyler yapar.

    class Server {
        public void pour (Coffee liquid) {
            new Cup().fillToTopWith(liquid);
        }

        public void pour (Wine liquid) {
            new WineGlass().fillHalfwayWith(liquid);
        }

        public void pour (Lemonade liquid, boolean ice) {
            Glass glass = new Glass();
            if (ice) {
                glass.fillToTopWith(new Ice());
            }
            glass.fillToTopWith(liquid);
        }
    }

Sanırım oylandı, çünkü tarihsel olarak aşırı yöntem yükü, nesne yönelimli paradigmada polimorfizmin bir parçası olarak görülmüyor. Yöntem aşırı yüklenmesi ve polimorfizm, bir programlama dilinin iki ortogonal, bağımsız özelliğidir.
Sergio Acosta

7
Burada cevabımda belirttiğim gibi, aynı fikirde değilim - iki özellik dik değil, ama yakından ilişkilidir. Polimorfizm! = Kalıtım. Benim oylamam var.
Peter Meyer

2
Başka bir deyişle, polimorfizm ve ad-hoc polimorfizm yazın. Gerektiği kadar eksiksiz olmasa bile bu cevabı vurguluyorum, çünkü hem aşırı yüklenmenin hem de geçersiz kılmanın polimorfizmle ilişkili olduğunu doğru bir şekilde ifade ediyor. OOP dillerindeki polimorfizmin sadece sınıf mirası ile elde edilebileceğini söylemek yanlıştır - Java ve C ++ dışında, birden fazla dağıtım, geçici polimorfizm, parametrik polimorfizm ve benzeri kavramları kullanabilen başka OOP dilleri olduğunu hatırlamamız gerekir. .
rsenna

2
@rsenna Bu eksik olabilir ancak soruyu geri kalan IMHO'dan çok daha iyi yanıtlar. Ayrıca, ad-hoc ve parametrik polimorfizmden bahsettiğiniz için çok güzel.
Valentin Radu

15

Aşırı yüklemenin cevap olmadığı doğru.

İkisi de geçersiz sayılmaz. Geçersiz kılma, polimorfizm elde etmenin yoludur. Polimorfizm, bir nesnenin davranışını türüne göre değiştirme yeteneğidir. Bu en iyi, polimorfizm sergileyen bir nesnenin arayanı, nesnenin ne tür bir özelliğin farkında olmadığında gösterilmektedir.


3
Değişen nesnenin davranışı değil, uygulanması olmalıdır. Aynı davranış, farklı uygulama, bu polimorfizm.
QBziZ

@QBziZ Davranışı , özellikle sıfat aynı tanımlamak gerekir . Davranış aynıysa, uygulamaları neden farklı olmalıdır? Birisinin belirli bir uygulamadan memnun olmaması, bu yüzden farklı bir uygulama gerektirmez.
Sнаđошƒаӽ

11

Özellikle aşırı yükleme veya geçersiz kılma demek tam resmi vermez. Çok biçimlilik, bir nesnenin davranışını türüne göre özelleştirme yeteneğidir.

Aynı isme sahip bir yöntemin farklı parametre türleri verebilmesi durumunda, aşırı yüklenmenin bir çeşit polimorfizm (parametrik polimorfizm) olduğu yönündeki bazı cevaplara katılmıyorum. Bunun iyi bir örneği operatör aşırı yüklemesidir. "+" Tanımlamak için "+" tanımlayabilirsiniz - örneğin dizeler veya int'ler - ve bu türler temelinde "+" farklı davranır.

Polimorfizm ayrıca, temel tipte soyut veya sanal olabilmelerine rağmen, kalıtım ve geçersiz kılma yöntemlerini içerir. Kalıtım temelli polimorfizm açısından, Java sadece polimorfik davranışı temel tür zincirininki ile sınırlayan tek sınıf kalıtımını destekler. Java, polimorfik davranışın başka bir biçimi olan çoklu arayüzlerin uygulanmasını destekler.


Söz konusu kelimelerin genel olarak ne anlama geldiği konusunda haklısınız, ancak programlama bağlamında, insanlar "polimorfizm" derken, her zaman "kalıtım temelli polimorfizm" anlamına gelir. İlginç bir nokta, ama polimorfizmi bu şekilde tanımlamanın insanları şaşırtacağını düşünüyorum.
The Digital Gabeg

Polimorfizmi sadece kalıtım açısından açıklamak daha kolay olabilir, ancak bu özel sorunun sorulma şekli parametrik polimorfizmi de tarif etmenin ihtiyatlı olduğunu düşünüyorum.
Patrick McElhaney

4
Açık olmak gerekirse, bence farklı formlar belirtilmelidir - ki bu da yeterince yapmadım - çünkü burada mutlak olarak sunulan birkaç cevap var. "Programcı bağlamında ..." polimorfizm "her zaman" kalıtım temelli polimorfizm "anlamına geldiğine saygılı değilim
Peter Meyer

2
aşırı yüklemenin Ad-hoc_polymorphism en.wikipedia.org/wiki/…
Manu

Aşağıda “Dijital Gabeg” ile hemfikirim. OOP tartışıyorsanız, polimorfizm genellikle alt tip polimorfizm anlamına gelir ve eğer tip teorisi hakkında tartışıyorsanız, herhangi bir tür polimorfizm anlamına gelir.
Manu

7

Polimorfizm basitçe "Birçok Form" anlamına gelir.

Hiç miras olmayan arayüz uygulaması polimorfik ihtiyaçlara hizmet ettiği için ... bir miras almayı GEREKTİRMEZ. Tartışmalı olarak, arayüz uygulaması polimorfik ihtiyaçlara kalıtımdan daha iyi "Daha iyi" hizmet eder.

Örneğin, uçabilecek her şeyi tanımlamak için bir süper sınıf yaratır mısınız? Düşünmemeliyim. En iyi şekilde, uçuşu tanımlayan bir arabirim oluşturmak ve onu bırakmak için size hizmet edilir.

Bu nedenle, arabirimler davranışı ve yöntem adları davranışı (programcıya) açıkladığından, yöntem aşırı yüklemesini daha az bir polimorfizm biçimi olarak görmek çok zor değildir.


2
Kesinlikle en iyi cevap. Polimorfizm, isimler (sınıflar) veya fiiller (yöntemler) olsun, tüm dil yapılarına uygulanabilir.
Radu Gasler

6

Klasik örnek, Köpekler ve kediler hayvandır, hayvanlar makeNoise yöntemine sahiptir. Onları makeNoise çağıran bir dizi hayvan üzerinden yinelenebilir ve orada ilgili uygulama yapacaklarını bekliyoruz.

Çağıran kodun hangi spesifik hayvan olduklarını bilmek zorunda değildir.

Ben polimorfizm olarak düşündüğüm şey bu.


4

Polimorfizm, bir nesnenin birden çok biçimde görünme yeteneğidir. Bu, değiştirilebilir bir nesne ailesi oluşturmak için miras ve sanal işlevlerin kullanılmasını içerir. Temel sınıf, uygulama gerektirdiği gibi muhtemelen uygulanmayan veya varsayılan uygulamalarla sanal işlevlerin prototiplerini içerir ve türetilmiş çeşitli sınıfların her biri, farklı davranışları etkilemek için bunları farklı şekilde uygular.


4

ne:

Aşırı yükleme, farklı parametreleri alan aynı işlev adına sahip olduğunuz zamandır.

Geçersiz kılma, bir çocuk sınıfının bir ebeveynin yöntemini kendi yöntemiyle değiştirmesidir (bu kendi içinde polimorfizm oluşturmaz).

Polimorfizm geç bağlanmadır, örn. Temel sınıf (ebeveyn) yöntemleri çağrılır, ancak çalışma zamanı gerçek nesnenin ne olduğunu bilene kadar değil - yöntemleri farklı olan bir çocuk sınıfı olabilir. Bunun nedeni, bir temel sınıfın tanımlandığı yerlerde herhangi bir alt sınıfın kullanılabilmesidir.

Java'da koleksiyon kitaplığıyla çok biçimliliği çok görüyorsunuz:

int countStuff(List stuff) {
  return stuff.size();
}

Liste temel sınıftır, bir liste gibi davrandığı sürece bağlantılı bir liste, vektör, dizi veya özel liste uygulaması sayıyorsanız, derleyicinin hiçbir fikri yoktur:

List myStuff = new MyTotallyAwesomeList();
int result = countStuff(myStuff);

Eğer aşırı yükleme yapsaydınız:

int countStuff(LinkedList stuff) {...}
int countStuff(ArrayList stuff) {...}
int countStuff(MyTotallyAwesomeList stuff) {...}
etc...

ve doğru countStuff () sürümü, parametreleri eşleştirmek için derleyici tarafından seçilecektir.


4

Her ne kadar, Polimorfizm bu yazıda çok ayrıntılı olarak açıklanmıştır, ancak bunun neden bir kısmına daha fazla vurgu yapmak istiyorum.

Polimorfizm herhangi bir OOP dilinde neden bu kadar önemlidir?

Miras / Polimorfizm olan ve olmayan bir TV için basit bir uygulama oluşturmaya çalışalım. Uygulamanın her sürümünü yayınlayın, küçük bir retrospektif yapıyoruz.

Diyelim ki, bir TV şirketinde yazılım mühendisisiniz ve kullanıcı komutunda değerlerini artırmak ve azaltmak için Ses Düzeyi, Parlaklık ve Renk denetleyicileri için yazılım yazmanız isteniyor.

Bu özelliklerin her biri için sınıflar ekleyerek

  1. set: - Bir denetleyicinin değerini ayarlamak için (varsayalım ki denetleyiciye özel kod var)
  2. get: - Bir denetleyicinin değerini almak için (varsayalım ki denetleyiciye özel kod var)
  3. ayarlayın: - Girişi doğrulamak ve bir denetleyici ayarlamak için. (Genel doğrulamalar .. denetleyicilerden bağımsız olarak)
  4. kontrolörler ile kullanıcı giriş eşlemesi: - Kullanıcı girişini ve kontrolörleri buna göre çağırmak için.

Uygulama Sürümü 1

import java.util.Scanner;    
class VolumeControllerV1 {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class  BrightnessControllerV1 {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class ColourControllerV1    {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

/*
 *       There can be n number of controllers
 * */
public class TvApplicationV1 {
    public static void main(String[] args)  {
        VolumeControllerV1 volumeControllerV1 = new VolumeControllerV1();
        BrightnessControllerV1 brightnessControllerV1 = new BrightnessControllerV1();
        ColourControllerV1 colourControllerV1 = new ColourControllerV1();


        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println("Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV1.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV1.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV1.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV1.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV1.adjust(5);
                    break;
                }
                case 6: {
                colourControllerV1.adjust(-5);
                break;
            }
            default:
                System.out.println("Shutting down...........");
                break OUTER;
        }

    }
    }
}

Artık dağıtılmaya hazır ilk çalışma uygulamamız var. Şimdiye kadar yapılan çalışmaları analiz etme zamanı.

TV Uygulama Sürümü 1

  1. Ayarlama (int değeri) kodu her üç sınıfta da yinelenir. Kod yinelenmesini en aza indirmek istiyorsunuz. (Ancak ortak kodu düşünmediniz ve yinelenen kodlardan kaçınmak için bazı süper sınıfa taşıdınız)

Başvurunuz beklendiği gibi çalıştığı sürece bununla yaşamaya karar verdiniz.

Bazen patronunuz size geri döner ve mevcut uygulamaya sıfırlama işlevselliği eklemenizi ister. Sıfırla, üç denetleyicinin üçünü de kendi varsayılan değerlerine ayarlar.

Yeni işlevsellik için yeni bir sınıf (ResetFunctionV2) yazmaya başlarsınız ve bu yeni özellik için kullanıcı giriş eşleme kodunu eşlersiniz.

Uygulama Sürümü 2

import java.util.Scanner;
class VolumeControllerV2    {

    private int defaultValue = 25;
    private int value;

    int getDefaultValue() {
        return defaultValue;
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class  BrightnessControllerV2   {

    private int defaultValue = 50;
    private int value;
    int get()    {
        return value;
    }
    int getDefaultValue() {
        return defaultValue;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class ColourControllerV2    {

    private int defaultValue = 40;
    private int value;
    int get()    {
        return value;
    }
    int getDefaultValue() {
        return defaultValue;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

class ResetFunctionV2 {

    private VolumeControllerV2 volumeControllerV2 ;
    private BrightnessControllerV2 brightnessControllerV2;
    private ColourControllerV2 colourControllerV2;

    ResetFunctionV2(VolumeControllerV2 volumeControllerV2, BrightnessControllerV2 brightnessControllerV2, ColourControllerV2 colourControllerV2)  {
        this.volumeControllerV2 = volumeControllerV2;
        this.brightnessControllerV2 = brightnessControllerV2;
        this.colourControllerV2 = colourControllerV2;
    }
    void onReset()    {
        volumeControllerV2.set(volumeControllerV2.getDefaultValue());
        brightnessControllerV2.set(brightnessControllerV2.getDefaultValue());
        colourControllerV2.set(colourControllerV2.getDefaultValue());
    }
}
/*
 *       so on
 *       There can be n number of controllers
 *
 * */
public class TvApplicationV2 {
    public static void main(String[] args)  {
        VolumeControllerV2 volumeControllerV2 = new VolumeControllerV2();
        BrightnessControllerV2 brightnessControllerV2 = new BrightnessControllerV2();
        ColourControllerV2 colourControllerV2 = new ColourControllerV2();

        ResetFunctionV2 resetFunctionV2 = new ResetFunctionV2(volumeControllerV2, brightnessControllerV2, colourControllerV2);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV2.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV2.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV2.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV2.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV2.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV2.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV2.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

Böylece uygulamanızı Sıfırla özelliği ile hazır hale getirirsiniz. Ama şimdi bunu fark etmeye başlıyorsun

TV Uygulaması Sürüm 2'deki sorunlar

  1. Ürüne yeni bir denetleyici eklendiğinde, Özellik kodunu sıfırla seçeneğini değiştirmeniz gerekir.
  2. Denetleyicinin sayısı çok yükselirse, denetleyicilerin referanslarını tutma konusunda sorun yaşarsınız.
  3. Sıfırlama özellik kodu, tüm denetleyiciler Sınıfının koduyla (varsayılan değerleri almak ve ayarlamak için) sıkıca bağlıdır.
  4. Sıfırlama özellik sınıfı (ResetFunctionV2), Controller sınıfının (ayar) istenmeyen diğer yöntemlerine erişebilir.

Aynı zamanda, Patronunuzdan, her kontrol cihazının, başlangıçta, şirketin internet üzerinden barındırılan sürücü deposundan sürücünün en son sürümünü kontrol etmesi gereken bir özellik eklemeniz gerekebileceğini duyuyorsunuz.

Şimdi eklenecek bu yeni özelliğin Sıfırlama özelliğine benzediğini düşünmeye başlıyorsunuz ve uygulamanızı yeniden hesaba katmazsanız Uygulama Sorunları (V2) çarpılacaktır.

Kalıtım kullanmayı düşünmeye başlarsınız, böylece JAVA'nın polimorfik yeteneğinden yararlanabilirsiniz ve yeni bir soyut sınıf (ControllerV3) eklersiniz.

  1. Get and set yönteminin imzasını bildirin.
  2. Daha önce tüm denetleyiciler arasında çoğaltılan ayarlama yöntemi uygulamasını içerir.
  3. Polimorfizmden yararlanarak sıfırlama özelliğinin kolayca uygulanabilmesi için setDefault yöntemini bildirin.

Bu geliştirmelerle TV uygulamanızın 3. versiyonunu yanınızda hazır hale getireceksiniz.

Uygulama Sürümü 3

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

abstract class ControllerV3 {
    abstract void set(int value);
    abstract int get();
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
    abstract void setDefault();
}
class VolumeControllerV3 extends ControllerV3   {

    private int defaultValue = 25;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
}
class  BrightnessControllerV3  extends ControllerV3   {

    private int defaultValue = 50;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
}
class ColourControllerV3 extends ControllerV3   {

    private int defaultValue = 40;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
}

class ResetFunctionV3 {

    private List<ControllerV3> controllers = null;

    ResetFunctionV3(List<ControllerV3> controllers)  {
        this.controllers = controllers;
    }
    void onReset()    {
        for (ControllerV3 controllerV3 :this.controllers)  {
            controllerV3.setDefault();
        }
    }
}
/*
 *       so on
 *       There can be n number of controllers
 *
 * */
public class TvApplicationV3 {
    public static void main(String[] args)  {
        VolumeControllerV3 volumeControllerV3 = new VolumeControllerV3();
        BrightnessControllerV3 brightnessControllerV3 = new BrightnessControllerV3();
        ColourControllerV3 colourControllerV3 = new ColourControllerV3();

        List<ControllerV3> controllerV3s = new ArrayList<>();
        controllerV3s.add(volumeControllerV3);
        controllerV3s.add(brightnessControllerV3);
        controllerV3s.add(colourControllerV3);

        ResetFunctionV3 resetFunctionV3 = new ResetFunctionV3(controllerV3s);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV3.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV3.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV3.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV3.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV3.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV3.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV3.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

Her ne kadar V2 sayı listesinde listelenen Sorunun çoğu hariç

TV Uygulaması Sürüm 3'teki Sorunlar

  1. Sıfırlama özelliği sınıfı (ResetFunctionV3), Controller sınıfının (ayar) istenmeyen diğer yöntemlerine erişebilir.

Yine, bu sorunu çözmeyi düşünüyorsunuz, çünkü şimdi uygulamak için başka bir özelliğiniz (başlangıçta sürücü güncellemesi) var. Düzeltmezseniz, yeni özelliklere de kopyalanacaktır.

Yani soyut sınıfta tanımlanan sözleşmeyi bölebilir ve

  1. Sıfırlama özelliği.
  2. Sürücü güncellemesi.

Ve 1. beton sınıfınızın bunları aşağıdaki gibi uygulamasını sağlayın

Uygulama Sürümü 4

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

interface OnReset {
    void setDefault();
}
interface OnStart {
    void checkForDriverUpdate();
}
abstract class ControllerV4 implements OnReset,OnStart {
    abstract void set(int value);
    abstract int get();
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

class VolumeControllerV4 extends ControllerV4 {

    private int defaultValue = 25;
    private int value;
    @Override
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for VolumeController .... Done");
    }
}
class  BrightnessControllerV4 extends ControllerV4 {

    private int defaultValue = 50;
    private int value;
    @Override
    int get()    {
        return value;
    }
    @Override
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }

    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for BrightnessController .... Done");
    }
}
class ColourControllerV4 extends ControllerV4 {

    private int defaultValue = 40;
    private int value;
    @Override
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for ColourController .... Done");
    }
}
class ResetFunctionV4 {

    private List<OnReset> controllers = null;

    ResetFunctionV4(List<OnReset> controllers)  {
        this.controllers = controllers;
    }
    void onReset()    {
        for (OnReset onreset :this.controllers)  {
            onreset.setDefault();
        }
    }
}
class InitializeDeviceV4 {

    private List<OnStart> controllers = null;

    InitializeDeviceV4(List<OnStart> controllers)  {
        this.controllers = controllers;
    }
    void initialize()    {
        for (OnStart onStart :this.controllers)  {
            onStart.checkForDriverUpdate();
        }
    }
}
/*
*       so on
*       There can be n number of controllers
*
* */
public class TvApplicationV4 {
    public static void main(String[] args)  {
        VolumeControllerV4 volumeControllerV4 = new VolumeControllerV4();
        BrightnessControllerV4 brightnessControllerV4 = new BrightnessControllerV4();
        ColourControllerV4 colourControllerV4 = new ColourControllerV4();
        List<ControllerV4> controllerV4s = new ArrayList<>();
        controllerV4s.add(brightnessControllerV4);
        controllerV4s.add(volumeControllerV4);
        controllerV4s.add(colourControllerV4);

        List<OnStart> controllersToInitialize = new ArrayList<>();
        controllersToInitialize.addAll(controllerV4s);
        InitializeDeviceV4 initializeDeviceV4 = new InitializeDeviceV4(controllersToInitialize);
        initializeDeviceV4.initialize();

        List<OnReset> controllersToReset = new ArrayList<>();
        controllersToReset.addAll(controllerV4s);
        ResetFunctionV4 resetFunctionV4 = new ResetFunctionV4(controllersToReset);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV4.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV4.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV4.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV4.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV4.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV4.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV4.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

Şimdi karşılaştığınız tüm sorunlara değinildi ve Miras ve Çok Biçimlilik kullanımı ile

  1. Uygulamanın çeşitli bölümlerini gevşek bir şekilde bağlı tutun. (Sıfırla veya Sürücü Güncelleme özelliği bileşenlerinin gerçek denetleyici sınıflarından (Hacim, Parlaklık ve Renk) haberdar edilmesine gerek yoktur, OnReset veya OnStart uygulayan herhangi bir sınıf Sıfırlama veya Sürücü Güncelleme özelliği için kabul edilebilir bileşenleri).
  2. Uygulama geliştirmesi daha kolay hale gelir.
  3. Soyutlama katmanını koru.

Bu yardımcı olur umarım :-)


3

Aşırı yükleme terimi, aynı ada sahip bir şeyin, genellikle farklı parametre listelerine sahip yöntemlerin birden fazla sürümüne sahip olmak anlamına gelir

public int DoSomething(int objectId) { ... }
public int DoSomething(string objectName) { ... }

Bu işlevler aynı şeyi yapabilir, ancak onu bir kimlik veya adla arama seçeneğiniz vardır. Kalıtım, soyut sınıflar vb. İle ilgisi yoktur.

Geçersiz kılma, sorunuzda açıkladığınız gibi genellikle polimorfizmi ifade eder


2

Aynı ada ancak farklı parametrelere sahip 2 yöntem tanımladığınızda aşırı yükleme

geçersiz kılma, alt sınıfta aynı ada sahip bir işlev aracılığıyla temel sınıfın davranışını değiştirdiğiniz yerdir.

Dolayısıyla, polimorfizm geçersiz kılmakla ilgilidir, ancak aşırı yüklenmemektedir.

Ancak biri bana "Polimorfizm nedir?" Sorusu için "geçersiz kılmanın" basit bir cevabını verdiyse. Daha fazla açıklama isterim.


2

geçersiz kılma, üst düzey yöntemle (süper yöntem) aynı ad ve imzayla bir yöntem bildirerek miras alınan bir yöntemi gizlemeye benzer, bu sınıfa polimorfik bir davranış ekler. diğer bir deyişle, çağrılacak olan seviye yöntemi seçim kararı derleme zamanında değil çalışma zamanında verilecektir. bu arayüz ve uygulama kavramına yol açar.


2

polimorfizm nedir?

Java dersinden

Polimorfizmin sözlük tanımı, bir organizmanın veya türün birçok farklı biçime veya aşamaya sahip olabileceği biyolojide bir ilkeyi ifade eder. Bu ilke, nesne yönelimli programlama ve Java dili gibi diller için de uygulanabilir. Bir sınıfın alt sınıfları kendi benzersiz davranışlarını tanımlayabilir ve yine de üst sınıfın aynı işlevlerinden bazılarını paylaşabilir.

Örnekler ve tanım dikkate alınarak, geçersiz kılma cevabı kabul edilmelidir.

İkinci sorgunuzla ilgili olarak:

Uygulamasız bir yöntemi tanımlayan soyut bir temel sınıfınız varsa ve bu alt sınıfta bu yöntemi tanımladıysanız, bu hala geçersiz kılıyor mu?

Buna geçersiz kılma denir.

Farklı geçersiz kılma türlerini anlamak için bu örneğe bir göz atın.

  1. Temel sınıf hiçbir uygulama sağlamaz ve alt sınıf tüm yöntemi geçersiz kılmak zorundadır - (özet)
  2. Temel sınıf varsayılan uygulama sağlar ve alt sınıf davranışı değiştirebilir
  3. Alt sınıf, arayarak temel sınıf uygulamasına uzantı ekler super.methodName() , ilk ifade olarak
  4. Temel sınıf algoritmanın yapısını tanımlar (Şablon yöntemi) ve alt sınıf algoritmanın bir bölümünü geçersiz kılar

kod snippet'i:

import java.util.HashMap;

abstract class Game implements Runnable{

    protected boolean runGame = true;
    protected Player player1 = null;
    protected Player player2 = null;
    protected Player currentPlayer = null;

    public Game(){
        player1 = new Player("Player 1");
        player2 = new Player("Player 2");
        currentPlayer = player1;
        initializeGame();
    }

    /* Type 1: Let subclass define own implementation. Base class defines abstract method to force
        sub-classes to define implementation    
    */

    protected abstract void initializeGame();

    /* Type 2: Sub-class can change the behaviour. If not, base class behaviour is applicable */
    protected void logTimeBetweenMoves(Player player){
        System.out.println("Base class: Move Duration: player.PlayerActTime - player.MoveShownTime");
    }

    /* Type 3: Base class provides implementation. Sub-class can enhance base class implementation by calling
        super.methodName() in first line of the child class method and specific implementation later */
    protected void logGameStatistics(){
        System.out.println("Base class: logGameStatistics:");
    }
    /* Type 4: Template method: Structure of base class can't be changed but sub-class can some part of behaviour */
    protected void runGame() throws Exception{
        System.out.println("Base class: Defining the flow for Game:");  
        while ( runGame) {
            /*
            1. Set current player
            2. Get Player Move
            */
            validatePlayerMove(currentPlayer);  
            logTimeBetweenMoves(currentPlayer);
            Thread.sleep(500);
            setNextPlayer();
        }
        logGameStatistics();
    }
    /* sub-part of the template method, which define child class behaviour */
    protected abstract void validatePlayerMove(Player p);

    protected void setRunGame(boolean status){
        this.runGame = status;
    }
    public void setCurrentPlayer(Player p){
        this.currentPlayer = p;
    }
    public void setNextPlayer(){
        if ( currentPlayer == player1) {
            currentPlayer = player2;
        }else{
            currentPlayer = player1;
        }
    }
    public void run(){
        try{
            runGame();
        }catch(Exception err){
            err.printStackTrace();
        }
    }
}

class Player{
    String name;
    Player(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

/* Concrete Game implementation  */
class Chess extends Game{
    public Chess(){
        super();
    }
    public void initializeGame(){
        System.out.println("Child class: Initialized Chess game");
    }
    protected void validatePlayerMove(Player p){
        System.out.println("Child class: Validate Chess move:"+p.getName());
    }
    protected void logGameStatistics(){
        super.logGameStatistics();
        System.out.println("Child class: Add Chess specific logGameStatistics:");
    }
}
class TicTacToe extends Game{
    public TicTacToe(){
        super();
    }
    public void initializeGame(){
        System.out.println("Child class: Initialized TicTacToe game");
    }
    protected void validatePlayerMove(Player p){
        System.out.println("Child class: Validate TicTacToe move:"+p.getName());
    }
}

public class Polymorphism{
    public static void main(String args[]){
        try{

            Game game = new Chess();
            Thread t1 = new Thread(game);
            t1.start();
            Thread.sleep(1000);
            game.setRunGame(false);
            Thread.sleep(1000);

            game = new TicTacToe();
            Thread t2 = new Thread(game);
            t2.start();
            Thread.sleep(1000);
            game.setRunGame(false);

        }catch(Exception err){
            err.printStackTrace();
        }       
    }
}

çıktı:

Child class: Initialized Chess game
Base class: Defining the flow for Game:
Child class: Validate Chess move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate Chess move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:
Child class: Add Chess specific logGameStatistics:
Child class: Initialized TicTacToe game
Base class: Defining the flow for Game:
Child class: Validate TicTacToe move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate TicTacToe move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:

2

Bence sizler kavramları karıştırıyorsunuz. Polimorfizm , bir nesnenin çalışma zamanında farklı davranma yeteneğidir. Bunu başarmak için iki gereksinime ihtiyacınız vardır:

  1. Geç bağlama
  2. Kalıtım.

Aşırı yüklemenin, kullandığınız dile bağlı olarak geçersiz kılmadan farklı bir şey ifade ettiğini söylemek . Örneğin Java'da geçersiz kılma değil aşırı yükleme var . Temel sınıfından farklı imzaya sahip aşırı yüklenmiş yöntemler alt sınıfta mevcuttur. Aksi takdirde geçersiz kılınırlar (lütfen bakın, şimdi temel sınıf yönteminizi nesnenin dışından çağırmanın bir yolu olmadığı gerçeğine bakın).

Ancak C ++ bu öyle değil. İmzanın aynı olup olmadığı (farklı miktar, farklı tür) bağımsız olarak aşırı yüklenmiş herhangi bir yöntem de geçersiz kılınır . Yani, taban sınıf 'yöntemi, alt sınıf nesnesinin dışından çağrıldığında artık alt sınıfta kullanılamaz.

Yani cevap, Java kullanımı aşırı yüklenmesi hakkında konuşurken . Başka bir dilde c ++ 'da olduğu gibi farklı olabilir


1

Polimorfizm, anlamıyla ilgili olduğu sürece daha olasıdır ... java'da OVERRIDING

Her şey SAME nesnesinin farklı durumlarda farklı davranışı ile ilgilidir (Programlama yolunda ... farklı ARGUMENTS diyebilirsiniz)

Aşağıdaki örnek anlamanıza yardımcı olacağını düşünüyorum ... PURE java kodu olmasa da ...

     public void See(Friend)
     {
        System.out.println("Talk");
     }

Ama eğer ARGÜMANI değiştirirsek ... DAVRANIŞ değiştirilecek ...

     public void See(Enemy)
     {
        System.out.println("Run");
     }

Kişi (burada "Nesne") aynı ...


1

Çok biçimlilik bir nesnenin çoklu uygulamalarıdır ya da bir nesnenin birden çok biçimini söyleyebilirsiniz. Diyelim ki Animalssoyut temel sınıf olarak sınıfınız var ve movement()hayvanın hareket şeklini tanımlayan bir yöntem var . Şimdi gerçekte farklı hayvan çeşitlerimiz var ve bazıları farklı şekilde hareket ediyor, bazıları 2 ayaklı, diğerleri 4 ve bazıları bacaksız, vb movement(). Ancak, daha fazla sınıf yani sınıf Dogs Cats Fishvb tanımlamanız gerekir . Sonra bu sınıfları temel sınıftan genişletmeniz Animalsve yöntemini geçersiz kılmanız gerekir.movement() sahip olduğunuz her hayvana dayalı yeni bir hareket işlevselliği ile gerekir. Ayrıca kullanabilirsinizInterfacesbunu başarmak için. Buradaki anahtar kelime geçersiz kılıyor, aşırı yükleme farklı ve polimorfizm olarak kabul edilmiyor. aşırı yükleme ile "aynı adda" ancak aynı nesne veya sınıfta farklı parametrelerle birden fazla yöntem tanımlayabilirsiniz.


0

Polimorfizm, bir dilin tek bir arayüz kullanarak tekdüze bir şekilde muamele edilmiş farklı bir nesneye sahip olma kabiliyeti ile ilgilidir; bu nedenle geçersiz kılma ile ilgilidir, bu nedenle arabirim (veya temel sınıf) polimorfiktir, uygulayıcı geçersiz kılan nesnedir (aynı madalyanın iki yüzü)

her neyse, iki terim arasındaki fark c ++ gibi diğer diller kullanılarak daha iyi açıklanabilir: c ++ 'da bir polimorfik nesne, temel işlev sanal ise java karşılığı gibi davranır, ancak yöntem sanal değilse kod atlama statik olarak çözülür , ve gerçek tip çalışma zamanında kontrol edilmediğinden, polimorfizm, bir nesnenin ona erişmek için kullanılan arayüze bağlı olarak farklı davranma yeteneğini içerir; sahte kodda bir örnek vereyim:

class animal {
    public void makeRumor(){
        print("thump");
    }
}
class dog extends animal {
    public void makeRumor(){
        print("woff");
    }
}

animal a = new dog();
dog b = new dog();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

(makeRumor'un sanal OLMADIĞINI varsayalım)

java gerçekten bu düzeyde polimorfizm sunmaz (nesne dilimleme olarak da adlandırılır).

hayvan a = yeni köpek (); köpek b = yeni köpek ();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

her iki durumda da sadece woff yazacaktır .. a ve b sınıf köpeğine atıfta bulunduğu için



hayvan a = yeni köpek (); a köpek olarak inşa edildi ve "woff" yazdıracak. Yumru yazdırmak istiyorsanız, o zaman onu upcast gerekir. ((Hayvan) a) .makeRumor ()
Chris Cudmore

Bu referans upcasting, ama nesne hala bir köpek. Eğer bir hayvan olmasını istiyorsanız, nesneyi açıkça mahvetmelisiniz.
Chris Cudmore

Anladım. Soru Java olarak etiketlendi. C ++ ile cevap verdiniz. C ++ 'da doğru olabilirsiniz. Java'da kesinlikle doğruyum.
Chris Cudmore

burada bir kopya oluşturucu söz konusu olduğunda her zaman bir referans olması gerekir fredosaurus.com/notes-cpp/oop-condestructors/… üçüncü durum eşleşmeleri; yalnızca yaratılışın belirsizliğini gidermek için var olan yeni işleci yoksay.
Lorenzo Boccaccia

0
import java.io.IOException;

class Super {

    protected Super getClassName(Super s) throws IOException {
        System.out.println(this.getClass().getSimpleName() + " - I'm parent");
        return null;
    }

}

class SubOne extends Super {

    @Override
    protected Super getClassName(Super s)  {
        System.out.println(this.getClass().getSimpleName() + " - I'm Perfect Overriding");
        return null;
    }

}

class SubTwo extends Super {

    @Override
    protected Super getClassName(Super s) throws NullPointerException {
        System.out.println(this.getClass().getSimpleName() + " - I'm Overriding and Throwing Runtime Exception");
        return null;
    }

}

class SubThree extends Super {

    @Override
    protected SubThree getClassName(Super s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Returning SubClass Type");
        return null;
    }

}

class SubFour extends Super {

    @Override
    protected Super getClassName(Super s) throws IOException {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Throwing Narrower Exception ");
        return null;
    }

}

class SubFive extends Super {

    @Override
    public Super getClassName(Super s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and have broader Access ");
        return null;
    }

}

class SubSix extends Super {

    public Super getClassName(Super s, String ol) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading ");
        return null;
    }

}

class SubSeven extends Super {

    public Super getClassName(SubSeven s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading because Method signature (Argument) changed.");
        return null;
    }

}

public class Test{

    public static void main(String[] args) throws Exception {

        System.out.println("Overriding\n");

        Super s1 = new SubOne(); s1.getClassName(null);

        Super s2 = new SubTwo(); s2.getClassName(null);

        Super s3 = new SubThree(); s3.getClassName(null);

        Super s4 = new SubFour(); s4.getClassName(null);

        Super s5 = new SubFive(); s5.getClassName(null);

        System.out.println("Overloading\n");

        SubSix s6 = new SubSix(); s6.getClassName(null, null);

        s6 = new SubSix(); s6.getClassName(null);

        SubSeven s7 = new SubSeven(); s7.getClassName(s7);

        s7 = new SubSeven(); s7.getClassName(new Super());

    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.