RealNumber ve ComplexNumber mirası nasıl uygulanır?


11

Umarım çok akademik değil ...

SW kütüphanemde gerçek ve karmaşık sayılara ihtiyacım olduğunu varsayalım.

Göre olan-bir (ya da burada ) ilişki, gerçek sayı a, karmaşık sayının sanal kısmı b sadece 0 karmaşık sayı,.

Öte yandan, benim uygulama, çocuk ebeveyn genişletir, bu yüzden ebeveyn RealNumber gerçek parçası olurdu ve çocuk ComplexNumber hayali sanat eklerdi.

Ayrıca, kalıtımın kötü olduğuna dair bir görüş var .

Dün hatırlıyorum, üniversitede OOP öğrenirken, profesörüm, bu ikisinin mutlak değeri farklı hesaplandığı için mirasın iyi bir örneği olmadığını söyledi (ama bunun için yöntem aşırı yükleme / polimorfizm var, değil mi?) .. .

Deneyimlerim, DRY'yi çözmek için genellikle miras kullandığımızdan, sonuç olarak hiyerarşide genellikle yapay soyut sınıflarımız var (çoğu zaman gerçek bir dünyadan nesneleri temsil etmedikleri için isim bulmakta sorun yaşıyoruz).


7
bu önceki soruda ele alınmış
tatarcık

1
@gnat Ah adamım, kullanmak istediğim başka bir örnekti ... Teşekkürler!
Betlista

7
... Matematiksel anlamda "gerçek sayı karmaşık bir sayıdır" cümlesinin sadece değişmez sayılar için geçerli olduğuna dikkat edin , bu nedenle değişmez nesneler kullanırsanız, LSP ihlallerinden kaçınabilirsiniz (aynı zamanda kareler ve dikdörtgenler için de geçerlidir, buna bakın) SO cevap ).
Doc Brown

5
... Ayrıca karmaşık sayılar için mutlak değer hesaplamasının gerçek sayılar için de işe yaradığını unutmayın, bu yüzden profesörünüzün ne anlama geldiğinden emin değilim. "Abs ()" yöntemini değişmez bir karmaşık sayıya doğru bir şekilde uygular ve ondan "real" türetirseniz, Abs () yöntemi yine de doğru sonuçlar verir.
Doc Brown

Yanıtlar:


17

Matematiksel anlamda, gerçek bir sayı karmaşık bir sayı olsa bile, karmaşıktan gerçek türetmek iyi bir fikir değildir. Liskov İkame İlkesini (diğer şeylerin yanı sıra) türetilmiş bir sınıfın bir temel sınıfın özelliklerini gizlememesi gerektiğini söyleyerek ihlal eder.

Bu durumda, gerçek bir sayının karmaşık sayının hayali kısmını gizlemesi gerekir. Sadece gerçek parçaya ihtiyacınız varsa gizli bir kayan nokta numarası (hayali parça) saklamanın hiçbir anlamı olmadığı açıktır.

Bu temel olarak bir yorumda belirtilen dikdörtgen / kare örneğiyle aynı konudur.


2
Bugün bu "Liskow İkame Prensibi" ni birkaç kez gördüm, bunun hakkında daha fazla okumak zorunda kalacağım, çünkü bunu bilmiyorum.
Betlista

7
Gerçek bir sayının hayali kısmını, örneğin salt okunur bir yöntemle sıfır olarak bildirmek mükemmeldir. Ancak hayali kısmın sıfıra ayarlandığı yerde, bir gerçeği karmaşık bir sayı olarak uygulamak mantıklı değildir. Bu, kalıtımın yanıltıcı olduğu bir durumdur: arayüz kalıtımı tartışmalı olarak iyi olsa da, uygulama kalıtımı sorunlu bir tasarımla sonuçlanacaktır.
amon

4
Her ikisi de değişmez olduğu sürece, gerçek sayıların karmaşık sayılardan miras alınması mükemmel bir mantıklıdır. Ve yükü önemsemiyorsun.
Tekilleştirici

@ Duplicalicator: İlginç bir nokta. Değişmezlik birçok sorunu çözer, ancak bu durumda henüz tam olarak ikna olmadım. Bunu düşünmek zorundayım.
Frank Puffer

3

bu ikisinin mutlak değeri farklı bir kalıtım örneği olarak farklı hesaplanır

Bu aslında buradaki tüm miraslara karşı zorlayıcı bir neden değil, sadece önerilen class RealNumber<-> class ComplexNumbermodel.

Sen makul bir arabirim tanımlayabilirsiniz Number, hangi ikisi RealNumber ve ComplexNumberuygulamaya koyacak.

Bu gibi görünebilir

interface Number
{
    Number Add(Number rhs);
    Number Subtract(Number rhs);
    // ... etc
}

Ama sonra Numberbu işlemlerdeki diğer parametreleri, türüne thisyakın olabileceğiniz türetilmiş türle sınırlamak istersiniz.

interface Number<T>
{
    Number<T> Add(Number<T> rhs);
    Number<T> Subtract(Number<T> rhs);
    // ... etc
}

Bunun yerine alt tip polimorfizmi yerine yapısal polimorfizme izin veren bir dil kullanırsınız. İçin özel durumda sayılar, yalnızca aritmetik operatörleri aşırı yeteneğini gerekebilir.

complex operator + (complex lhs, complex rhs);
complex operator - (complex lhs, complex rhs);
// ... etc

Number frobnicate<Number>(List<Number> foos, Number bar); // uses arithmetic operations

0

Çözüm: Herkese açık bir RealNumbersınıfınız yok

Hayali sıfır olan karmaşık bir sayı döndürecek ComplexNumberstatik bir fabrika yöntemi olsaydı tamamen Tamam fromDouble(double)bulurdum. Daha sonra RealNumberbu ComplexNumberörnekte bir örnekte kullanacağınız tüm işlemleri kullanabilirsiniz .

Ama neden halk tarafından miras alınan bir RealNumbersınıfa sahip olmak istediğinizi / ihtiyacınızı görmekte zorlanıyorum . Genellikle bu nedenlerle kalıtım kullanılır (kafamdan, bazılarını kaçırırsam düzelt)

  • davranışı genişletmek. RealNumbersEkstra işlem yapamaz karmaşık numara yapamaz, bu yüzden bunu yapmanın bir anlamı yok.

  • soyut davranışın belirli bir uygulama ile uygulanması. Yana ComplexNumbersoyut olmamalı bu da geçerli değildir.

  • kodun yeniden kullanımı. ComplexNumberSınıfı kullanırsanız , kodun% 100'ünü yeniden kullanırsınız .

  • belirli bir görev için daha spesifik / verimli / doğru uygulama. Bu burada uygulanabilir, RealNumbersbazı işlevleri daha hızlı uygulayabilir. Ancak bu alt sınıf statikin arkasına gizlenmeli fromDouble(double)ve dışarıda bilinmemelidir. Bu şekilde hayali kısmı gizlemeye gerek kalmaz. Dış için sadece karmaşık sayılar olmalıdır (gerçek sayılar). Bu özel RealNumber sınıfını, karmaşık sayı sınıfında gerçek bir sayı ile sonuçlanan herhangi bir işlemden de döndürebilirsiniz. (Bu, sınıfların çoğu sayı sınıfı gibi değişmez olduğunu varsayar.)

Sıfır adında önemsiz oldukları için Sıfır adı verilen bir tamsayı alt sınıfı uygulamak ve bazı işlemleri sabit kodlamak gibidir. Her sıfır bir tamsayı olduğu için bunu yapabilirsiniz, ancak herkese açık hale getirmeyin, fabrika yönteminin arkasına saklayın.


Kanıtlamak için hiçbir kaynağım olmadığından, bazı oylar almak beni şaşırtmadı. Ayrıca başka kimsenin bir fikri yoksa, bunun için bir neden olabileceğinden şüpheleniyorum. Ama lütfen bana bunun neden yanlış olduğunu düşündüğünü ve nasıl daha iyi hale getireceğini söyle.
findusl

0

Gerçek bir sayının karmaşık bir sayı olduğunu söylemek, matematikte, özellikle de set teorisinde, bilgisayar biliminden daha fazla anlama sahiptir.
Matematikte diyoruz:

  • Gerçek sayı karmaşık bir sayıdır çünkü karmaşık sayılar kümesi gerçek sayılar kümesini içerir.
  • Rasyonel bir sayı gerçek bir sayıdır, çünkü gerçek sayılar kümesi rasyonel sayılar kümesini (ve irrasyonel sayılar kümesini) içerir.
  • Tamsayı rasyonel bir sayıdır, çünkü rasyonel sayılar kümesi tamsayılar kümesini içerir.

Ancak bu, kitaplığınızı bir RealNumber ve ComplexNumber sınıfı içerecek şekilde tasarlarken miras almanız gerektiği veya hatta kullanmanız gerektiği anlamına gelmez. In Etkili Java, İkinci Baskı Joshua Bloch tarafından; Madde 16, "Kompozisyonun Kalıtım Üzerine Favorisini" oluşturmaktadır. Bu öğede belirtilen sorunlardan kaçınmak için, RealNumber sınıfınızı tanımladıktan sonra, ComplexNumber sınıfınızda kullanılabilir:

public class ComplexNumber {
    private RealNumber realPart;
    private RealNumber imaginaryPart;

    // Implementation details are for you to write
}

Bu, Joshua Bloch tarafından tanımlanan sorunlardan kaçınırken, kodunuzu KURU tutmak için RealNumber sınıfınızı yeniden kullanmanın tüm gücünü sağlar.


0

Burada iki konu var. Birincisi, aynı sayıları, özellikle sayılar gibi ilkel türlerde, konteyner türleri ve içerik türleri için kullanmak yaygındır. Terimi double, örneğin, bir çift kesinlikli kayar nokta değeri ve bir depolanmış edilebilen bir kabın her ikisini tanımlamak için kullanılmaktadır.

İkinci konu, çeşitli nesnelerin okunabileceği kapsayıcılar arasındaki ilişkilerin nesnelerin kendileri arasındaki ilişkilerle aynı şekilde davranmasına rağmen, çeşitli nesnelerin yerleştirilebileceği kaplar arasında, içeriklerinin tersine davranabilmesidir. . Örneği olduğu bilinen her kafes, örneğini Cattutan bir kafes olacaktır Animal, ancak örneğini tutan bir kafes olması gerekmez SiameseCat. Öte yandan, tüm örneklerini tutabilecek her kafes, tüm örneklerini tutabilecek Catbir kafes olacaktır SiameseCat, ancak tüm örneklerini tutabilecek bir kafes olması gerekmez Animal. Tüm örneklerini tutabilecek Catve garanti edilebilecek tek kafes türü ,Cat, bir kafes Cat. Başka herhangi bir kafes ya kabul etmesi gereken bazı örneklerini Catkabul edemez ya da örnek olmayan şeyleri kabul edebilir Cat.

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.