How to implement RealNumber and ComplexNumber inheritance?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












8















Hopefully not too academic...



Let's say I need real and complex numbers in my SW library.



Based on is-a (or here) relationship, real number is a complex number, where b in imaginary part of complex number is simply 0.



On the other hand, my implementation would be, that child extends parent, so in parent RealNumber I'd have real part and child ComplexNumber would add imaginary art.



Also there is an opinion, that inheritance is evil.



I recall like yesterday, when I was learning OOP at university, my professor said, this is not a good example of inheritance as absolute value of those two is calculated differently (but for that we have method overloading/polymorfism, right?)...



My experience is, that we often use inheritance to solve DRY, as a result we have often artificial abstract classes in hierarchy (we often have problem to find names for as they do not represent objects from a real world).










share|improve this question



















  • 7





    this looks like covered in prior question: Should rectangle inherit from square?

    – gnat
    Jan 9 at 13:37







  • 1





    @gnat Oh man, that was another example I wanted to use... Thanks!

    – Betlista
    Jan 9 at 14:14






  • 7





    ... Note that the sentence "real number is a complex number" in the mathematical sense is only valid for immutable numbers, so if you use immutable objects, you can avoid the LSP violation (same holds also for squares and rectangles, see this SO answer).

    – Doc Brown
    Jan 9 at 15:20







  • 5





    ... Note further the absolute value calculation for complex numbers works also for real numbers, so I am not sure what your professor meant. If you implement an "Abs()" method correctly in an immutable complex number and derive a "real" from it, the Abs() method will still deliver correct results.

    – Doc Brown
    Jan 9 at 15:23







  • 3





    Possible duplicate of Should rectangle inherit from square?

    – BobDalgleish
    Jan 9 at 17:21















8















Hopefully not too academic...



Let's say I need real and complex numbers in my SW library.



Based on is-a (or here) relationship, real number is a complex number, where b in imaginary part of complex number is simply 0.



On the other hand, my implementation would be, that child extends parent, so in parent RealNumber I'd have real part and child ComplexNumber would add imaginary art.



Also there is an opinion, that inheritance is evil.



I recall like yesterday, when I was learning OOP at university, my professor said, this is not a good example of inheritance as absolute value of those two is calculated differently (but for that we have method overloading/polymorfism, right?)...



My experience is, that we often use inheritance to solve DRY, as a result we have often artificial abstract classes in hierarchy (we often have problem to find names for as they do not represent objects from a real world).










share|improve this question



















  • 7





    this looks like covered in prior question: Should rectangle inherit from square?

    – gnat
    Jan 9 at 13:37







  • 1





    @gnat Oh man, that was another example I wanted to use... Thanks!

    – Betlista
    Jan 9 at 14:14






  • 7





    ... Note that the sentence "real number is a complex number" in the mathematical sense is only valid for immutable numbers, so if you use immutable objects, you can avoid the LSP violation (same holds also for squares and rectangles, see this SO answer).

    – Doc Brown
    Jan 9 at 15:20







  • 5





    ... Note further the absolute value calculation for complex numbers works also for real numbers, so I am not sure what your professor meant. If you implement an "Abs()" method correctly in an immutable complex number and derive a "real" from it, the Abs() method will still deliver correct results.

    – Doc Brown
    Jan 9 at 15:23







  • 3





    Possible duplicate of Should rectangle inherit from square?

    – BobDalgleish
    Jan 9 at 17:21













8












8








8








Hopefully not too academic...



Let's say I need real and complex numbers in my SW library.



Based on is-a (or here) relationship, real number is a complex number, where b in imaginary part of complex number is simply 0.



On the other hand, my implementation would be, that child extends parent, so in parent RealNumber I'd have real part and child ComplexNumber would add imaginary art.



Also there is an opinion, that inheritance is evil.



I recall like yesterday, when I was learning OOP at university, my professor said, this is not a good example of inheritance as absolute value of those two is calculated differently (but for that we have method overloading/polymorfism, right?)...



My experience is, that we often use inheritance to solve DRY, as a result we have often artificial abstract classes in hierarchy (we often have problem to find names for as they do not represent objects from a real world).










share|improve this question
















Hopefully not too academic...



Let's say I need real and complex numbers in my SW library.



Based on is-a (or here) relationship, real number is a complex number, where b in imaginary part of complex number is simply 0.



On the other hand, my implementation would be, that child extends parent, so in parent RealNumber I'd have real part and child ComplexNumber would add imaginary art.



Also there is an opinion, that inheritance is evil.



I recall like yesterday, when I was learning OOP at university, my professor said, this is not a good example of inheritance as absolute value of those two is calculated differently (but for that we have method overloading/polymorfism, right?)...



My experience is, that we often use inheritance to solve DRY, as a result we have often artificial abstract classes in hierarchy (we often have problem to find names for as they do not represent objects from a real world).







design inheritance






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 9 at 20:14









mrflash818

1073




1073










asked Jan 9 at 13:33









BetlistaBetlista

21937




21937







  • 7





    this looks like covered in prior question: Should rectangle inherit from square?

    – gnat
    Jan 9 at 13:37







  • 1





    @gnat Oh man, that was another example I wanted to use... Thanks!

    – Betlista
    Jan 9 at 14:14






  • 7





    ... Note that the sentence "real number is a complex number" in the mathematical sense is only valid for immutable numbers, so if you use immutable objects, you can avoid the LSP violation (same holds also for squares and rectangles, see this SO answer).

    – Doc Brown
    Jan 9 at 15:20







  • 5





    ... Note further the absolute value calculation for complex numbers works also for real numbers, so I am not sure what your professor meant. If you implement an "Abs()" method correctly in an immutable complex number and derive a "real" from it, the Abs() method will still deliver correct results.

    – Doc Brown
    Jan 9 at 15:23







  • 3





    Possible duplicate of Should rectangle inherit from square?

    – BobDalgleish
    Jan 9 at 17:21












  • 7





    this looks like covered in prior question: Should rectangle inherit from square?

    – gnat
    Jan 9 at 13:37







  • 1





    @gnat Oh man, that was another example I wanted to use... Thanks!

    – Betlista
    Jan 9 at 14:14






  • 7





    ... Note that the sentence "real number is a complex number" in the mathematical sense is only valid for immutable numbers, so if you use immutable objects, you can avoid the LSP violation (same holds also for squares and rectangles, see this SO answer).

    – Doc Brown
    Jan 9 at 15:20







  • 5





    ... Note further the absolute value calculation for complex numbers works also for real numbers, so I am not sure what your professor meant. If you implement an "Abs()" method correctly in an immutable complex number and derive a "real" from it, the Abs() method will still deliver correct results.

    – Doc Brown
    Jan 9 at 15:23







  • 3





    Possible duplicate of Should rectangle inherit from square?

    – BobDalgleish
    Jan 9 at 17:21







7




7





this looks like covered in prior question: Should rectangle inherit from square?

– gnat
Jan 9 at 13:37






this looks like covered in prior question: Should rectangle inherit from square?

– gnat
Jan 9 at 13:37





1




1





@gnat Oh man, that was another example I wanted to use... Thanks!

– Betlista
Jan 9 at 14:14





@gnat Oh man, that was another example I wanted to use... Thanks!

– Betlista
Jan 9 at 14:14




7




7





... Note that the sentence "real number is a complex number" in the mathematical sense is only valid for immutable numbers, so if you use immutable objects, you can avoid the LSP violation (same holds also for squares and rectangles, see this SO answer).

– Doc Brown
Jan 9 at 15:20






... Note that the sentence "real number is a complex number" in the mathematical sense is only valid for immutable numbers, so if you use immutable objects, you can avoid the LSP violation (same holds also for squares and rectangles, see this SO answer).

– Doc Brown
Jan 9 at 15:20





5




5





... Note further the absolute value calculation for complex numbers works also for real numbers, so I am not sure what your professor meant. If you implement an "Abs()" method correctly in an immutable complex number and derive a "real" from it, the Abs() method will still deliver correct results.

– Doc Brown
Jan 9 at 15:23






... Note further the absolute value calculation for complex numbers works also for real numbers, so I am not sure what your professor meant. If you implement an "Abs()" method correctly in an immutable complex number and derive a "real" from it, the Abs() method will still deliver correct results.

– Doc Brown
Jan 9 at 15:23





3




3





Possible duplicate of Should rectangle inherit from square?

– BobDalgleish
Jan 9 at 17:21





Possible duplicate of Should rectangle inherit from square?

– BobDalgleish
Jan 9 at 17:21










5 Answers
5






active

oldest

votes


















16














Even if in a mathematical sense, a real number is a complex number, it is not a good idea to derive real from complex. It violates the Liskov Substitution Principle saying (among other things) that a derived class should not hide properties of a base class.



In this case a real number would have to hide the imaginary part of the complex number. It is clear that it makes no sense to store a hidden floating point number (imaginary part) if you only need the real part.



This is basically the same issue as the rectangle/square example mentioned in a comment.






share|improve this answer




















  • 2





    Today I saw this "Liskow Substitution Principle" several times, I'll have to read more about it, because I do not know that.

    – Betlista
    Jan 9 at 14:17






  • 7





    It is perfectly fine to report the imaginary part of a real number as zero, e.g. through a read-only method. But it makes no sense to implement a real as a complex number where the imaginary part is set to zero. This is exactly a case where inheritance is misleading: while interface inheritance would arguably be fine here, implementation inheritance would result in a problematic design.

    – amon
    Jan 9 at 14:26






  • 4





    It makes perfect sense to have real numbers inherit from complex numbers, as long as both are immutable. And you don't mind the overhead.

    – Deduplicator
    Jan 9 at 19:20











  • @Deduplicator: Interesting point. Immutability resolves lots of issues but I am not fully convinced yet in this case. Have to think about it.

    – Frank Puffer
    Jan 9 at 20:21


















3















not a good example of inheritance as absolute value of those two is calculated differently




This isn't actually a compelling reason against all inheritance here, just the proposed class RealNumber <-> class ComplexNumber model.



You might reasonably define an interface Number, which both RealNumber and ComplexNumber would implement.



That might look like



interface Number

Number Add(Number rhs);
Number Subtract(Number rhs);
// ... etc



But then you'd want to constrain the other Number parameters in these operations to be the same derived type as this, which you can get close to with



interface Number<T>

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



Or instead you'd use a language that allowed structural polymorphism, instead of subtype polymorphism. For the specific case of numbers, you might only need the ability to overload arithmetic operators.



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

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





share|improve this answer






























    0














    Solution: Do not have a public RealNumber class



    I would find it totally OK if ComplexNumber had a static factory method fromDouble(double) that would return a complex number with imaginary being zero. You can then use all the operations that you would use on a RealNumber instance on this ComplexNumber instance.



    But I have trouble seeing why you would want/need to have a public inherited RealNumber class. Usually inheritance is used for these reasons (out of my head, correct me if missed some)



    • extending the behaviour. RealNumbers cannot do any extra operations complex number can't do, so no point in doing this.


    • implementing abstract behaviour with a specific implementation. Since ComplexNumber should not be abstract this also does not apply.


    • code reuse. If you just use the ComplexNumber class you reuse 100% of the code.


    • more specific/efficient/accurate implementation for a specific task. This could be applied here, RealNumbers could implement some functionalities faster. But then this subclass should be hidden behind the static fromDouble(double) and should not be known outside. This way it would not need to hide the imaginary part. For the outside there should only be complex numbers (which real numbers are). You could also return this private RealNumber class from any operations in the complex number class that results in a real number. (This assumes the classes are immutable as most number classes.)


    It is like implementing a subclass of Integer that is called Zero and hardcode some of the operations since they are trivial for zero. You could do this, as every zero is an integer, but don't make it public, hide it behind a factory method.






    share|improve this answer

























    • I am not surprised to get some downvote, since I have no source to prove. Also if nobody else had an idea, I always suspect there might be some reason for that. But please tell me why you think it is wrong and how you would make it better.

      – findusl
      Jan 10 at 9:06


















    0














    Saying that a real number is a complex number has more meaning in mathematics, especially set theory, than computer science.

    In mathematics we say :



    • A real number is a complex number because the set of complex numbers
      includes the set of real numbers.

    • A rational number is a real number because the set of real numbers includes the set of rational numbers (and the set of
      irrational numbers).

    • An integer is a rational number because the set of rational numbers includes the set of integers.

    However, this does not mean you must, or even should, use inheritance when designing your library to include a RealNumber and ComplexNumber class. In Effective Java, Second Edition by Joshua Bloch; Item 16 is "Favor Composition Over Inheritance". To avoid the problems mentioned in that item, once you have your RealNumber class defined, it can be used in your ComplexNumber class:



    public class ComplexNumber 
    private RealNumber realPart;
    private RealNumber imaginaryPart;

    // Implementation details are for you to write



    This allows you all the power of reusing your RealNumber class to keep your code DRY while avoiding the issues identified by Joshua Bloch.






    share|improve this answer






























      0














      There are two issues here. The first is that it's common to use the same terms for the types of containers and the types of their contents, especially with primitive types like numbers. The term double, for example, is used to describe both a double-precision floating-point value and a container in which one may be stored.



      The second issue is that while is-a relationships among containers from which various types of objects can be read behave the same as the relationships among the objects themselves, those among containers into which various types of objects can be placed behave opposite those among their contents. Every cage that's known to hold an instance of Cat will be a cage that holds an instance of Animal, but need not be be a cage that holds an instance of SiameseCat. On the other hand, every cage that can hold all instances of Cat will be a cage that can hold all instances of SiameseCat, but need not be a cage that can hold all instances of Animal. The only kind of cage that can hold all instances of Cat and can be guaranteed never hold anything other than an instance of Cat, is a cage of Cat. Any other kind of cage would either be incapable of accepting some instances of Cat that it should accept, or would be capable of accepting things that are not instances of Cat.






      share|improve this answer






















        Your Answer








        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "131"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader:
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        ,
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );













        draft saved

        draft discarded


















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f385185%2fhow-to-implement-realnumber-and-complexnumber-inheritance%23new-answer', 'question_page');

        );

        Post as a guest















        Required, but never shown

























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        16














        Even if in a mathematical sense, a real number is a complex number, it is not a good idea to derive real from complex. It violates the Liskov Substitution Principle saying (among other things) that a derived class should not hide properties of a base class.



        In this case a real number would have to hide the imaginary part of the complex number. It is clear that it makes no sense to store a hidden floating point number (imaginary part) if you only need the real part.



        This is basically the same issue as the rectangle/square example mentioned in a comment.






        share|improve this answer




















        • 2





          Today I saw this "Liskow Substitution Principle" several times, I'll have to read more about it, because I do not know that.

          – Betlista
          Jan 9 at 14:17






        • 7





          It is perfectly fine to report the imaginary part of a real number as zero, e.g. through a read-only method. But it makes no sense to implement a real as a complex number where the imaginary part is set to zero. This is exactly a case where inheritance is misleading: while interface inheritance would arguably be fine here, implementation inheritance would result in a problematic design.

          – amon
          Jan 9 at 14:26






        • 4





          It makes perfect sense to have real numbers inherit from complex numbers, as long as both are immutable. And you don't mind the overhead.

          – Deduplicator
          Jan 9 at 19:20











        • @Deduplicator: Interesting point. Immutability resolves lots of issues but I am not fully convinced yet in this case. Have to think about it.

          – Frank Puffer
          Jan 9 at 20:21















        16














        Even if in a mathematical sense, a real number is a complex number, it is not a good idea to derive real from complex. It violates the Liskov Substitution Principle saying (among other things) that a derived class should not hide properties of a base class.



        In this case a real number would have to hide the imaginary part of the complex number. It is clear that it makes no sense to store a hidden floating point number (imaginary part) if you only need the real part.



        This is basically the same issue as the rectangle/square example mentioned in a comment.






        share|improve this answer




















        • 2





          Today I saw this "Liskow Substitution Principle" several times, I'll have to read more about it, because I do not know that.

          – Betlista
          Jan 9 at 14:17






        • 7





          It is perfectly fine to report the imaginary part of a real number as zero, e.g. through a read-only method. But it makes no sense to implement a real as a complex number where the imaginary part is set to zero. This is exactly a case where inheritance is misleading: while interface inheritance would arguably be fine here, implementation inheritance would result in a problematic design.

          – amon
          Jan 9 at 14:26






        • 4





          It makes perfect sense to have real numbers inherit from complex numbers, as long as both are immutable. And you don't mind the overhead.

          – Deduplicator
          Jan 9 at 19:20











        • @Deduplicator: Interesting point. Immutability resolves lots of issues but I am not fully convinced yet in this case. Have to think about it.

          – Frank Puffer
          Jan 9 at 20:21













        16












        16








        16







        Even if in a mathematical sense, a real number is a complex number, it is not a good idea to derive real from complex. It violates the Liskov Substitution Principle saying (among other things) that a derived class should not hide properties of a base class.



        In this case a real number would have to hide the imaginary part of the complex number. It is clear that it makes no sense to store a hidden floating point number (imaginary part) if you only need the real part.



        This is basically the same issue as the rectangle/square example mentioned in a comment.






        share|improve this answer















        Even if in a mathematical sense, a real number is a complex number, it is not a good idea to derive real from complex. It violates the Liskov Substitution Principle saying (among other things) that a derived class should not hide properties of a base class.



        In this case a real number would have to hide the imaginary part of the complex number. It is clear that it makes no sense to store a hidden floating point number (imaginary part) if you only need the real part.



        This is basically the same issue as the rectangle/square example mentioned in a comment.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 9 at 20:13









        Bob Gilmore

        1033




        1033










        answered Jan 9 at 14:11









        Frank PufferFrank Puffer

        3,92451333




        3,92451333







        • 2





          Today I saw this "Liskow Substitution Principle" several times, I'll have to read more about it, because I do not know that.

          – Betlista
          Jan 9 at 14:17






        • 7





          It is perfectly fine to report the imaginary part of a real number as zero, e.g. through a read-only method. But it makes no sense to implement a real as a complex number where the imaginary part is set to zero. This is exactly a case where inheritance is misleading: while interface inheritance would arguably be fine here, implementation inheritance would result in a problematic design.

          – amon
          Jan 9 at 14:26






        • 4





          It makes perfect sense to have real numbers inherit from complex numbers, as long as both are immutable. And you don't mind the overhead.

          – Deduplicator
          Jan 9 at 19:20











        • @Deduplicator: Interesting point. Immutability resolves lots of issues but I am not fully convinced yet in this case. Have to think about it.

          – Frank Puffer
          Jan 9 at 20:21












        • 2





          Today I saw this "Liskow Substitution Principle" several times, I'll have to read more about it, because I do not know that.

          – Betlista
          Jan 9 at 14:17






        • 7





          It is perfectly fine to report the imaginary part of a real number as zero, e.g. through a read-only method. But it makes no sense to implement a real as a complex number where the imaginary part is set to zero. This is exactly a case where inheritance is misleading: while interface inheritance would arguably be fine here, implementation inheritance would result in a problematic design.

          – amon
          Jan 9 at 14:26






        • 4





          It makes perfect sense to have real numbers inherit from complex numbers, as long as both are immutable. And you don't mind the overhead.

          – Deduplicator
          Jan 9 at 19:20











        • @Deduplicator: Interesting point. Immutability resolves lots of issues but I am not fully convinced yet in this case. Have to think about it.

          – Frank Puffer
          Jan 9 at 20:21







        2




        2





        Today I saw this "Liskow Substitution Principle" several times, I'll have to read more about it, because I do not know that.

        – Betlista
        Jan 9 at 14:17





        Today I saw this "Liskow Substitution Principle" several times, I'll have to read more about it, because I do not know that.

        – Betlista
        Jan 9 at 14:17




        7




        7





        It is perfectly fine to report the imaginary part of a real number as zero, e.g. through a read-only method. But it makes no sense to implement a real as a complex number where the imaginary part is set to zero. This is exactly a case where inheritance is misleading: while interface inheritance would arguably be fine here, implementation inheritance would result in a problematic design.

        – amon
        Jan 9 at 14:26





        It is perfectly fine to report the imaginary part of a real number as zero, e.g. through a read-only method. But it makes no sense to implement a real as a complex number where the imaginary part is set to zero. This is exactly a case where inheritance is misleading: while interface inheritance would arguably be fine here, implementation inheritance would result in a problematic design.

        – amon
        Jan 9 at 14:26




        4




        4





        It makes perfect sense to have real numbers inherit from complex numbers, as long as both are immutable. And you don't mind the overhead.

        – Deduplicator
        Jan 9 at 19:20





        It makes perfect sense to have real numbers inherit from complex numbers, as long as both are immutable. And you don't mind the overhead.

        – Deduplicator
        Jan 9 at 19:20













        @Deduplicator: Interesting point. Immutability resolves lots of issues but I am not fully convinced yet in this case. Have to think about it.

        – Frank Puffer
        Jan 9 at 20:21





        @Deduplicator: Interesting point. Immutability resolves lots of issues but I am not fully convinced yet in this case. Have to think about it.

        – Frank Puffer
        Jan 9 at 20:21













        3















        not a good example of inheritance as absolute value of those two is calculated differently




        This isn't actually a compelling reason against all inheritance here, just the proposed class RealNumber <-> class ComplexNumber model.



        You might reasonably define an interface Number, which both RealNumber and ComplexNumber would implement.



        That might look like



        interface Number

        Number Add(Number rhs);
        Number Subtract(Number rhs);
        // ... etc



        But then you'd want to constrain the other Number parameters in these operations to be the same derived type as this, which you can get close to with



        interface Number<T>

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



        Or instead you'd use a language that allowed structural polymorphism, instead of subtype polymorphism. For the specific case of numbers, you might only need the ability to overload arithmetic operators.



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

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





        share|improve this answer



























          3















          not a good example of inheritance as absolute value of those two is calculated differently




          This isn't actually a compelling reason against all inheritance here, just the proposed class RealNumber <-> class ComplexNumber model.



          You might reasonably define an interface Number, which both RealNumber and ComplexNumber would implement.



          That might look like



          interface Number

          Number Add(Number rhs);
          Number Subtract(Number rhs);
          // ... etc



          But then you'd want to constrain the other Number parameters in these operations to be the same derived type as this, which you can get close to with



          interface Number<T>

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



          Or instead you'd use a language that allowed structural polymorphism, instead of subtype polymorphism. For the specific case of numbers, you might only need the ability to overload arithmetic operators.



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

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





          share|improve this answer

























            3












            3








            3








            not a good example of inheritance as absolute value of those two is calculated differently




            This isn't actually a compelling reason against all inheritance here, just the proposed class RealNumber <-> class ComplexNumber model.



            You might reasonably define an interface Number, which both RealNumber and ComplexNumber would implement.



            That might look like



            interface Number

            Number Add(Number rhs);
            Number Subtract(Number rhs);
            // ... etc



            But then you'd want to constrain the other Number parameters in these operations to be the same derived type as this, which you can get close to with



            interface Number<T>

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



            Or instead you'd use a language that allowed structural polymorphism, instead of subtype polymorphism. For the specific case of numbers, you might only need the ability to overload arithmetic operators.



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

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





            share|improve this answer














            not a good example of inheritance as absolute value of those two is calculated differently




            This isn't actually a compelling reason against all inheritance here, just the proposed class RealNumber <-> class ComplexNumber model.



            You might reasonably define an interface Number, which both RealNumber and ComplexNumber would implement.



            That might look like



            interface Number

            Number Add(Number rhs);
            Number Subtract(Number rhs);
            // ... etc



            But then you'd want to constrain the other Number parameters in these operations to be the same derived type as this, which you can get close to with



            interface Number<T>

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



            Or instead you'd use a language that allowed structural polymorphism, instead of subtype polymorphism. For the specific case of numbers, you might only need the ability to overload arithmetic operators.



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

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






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jan 9 at 14:49









            CalethCaleth

            5,73611320




            5,73611320





















                0














                Solution: Do not have a public RealNumber class



                I would find it totally OK if ComplexNumber had a static factory method fromDouble(double) that would return a complex number with imaginary being zero. You can then use all the operations that you would use on a RealNumber instance on this ComplexNumber instance.



                But I have trouble seeing why you would want/need to have a public inherited RealNumber class. Usually inheritance is used for these reasons (out of my head, correct me if missed some)



                • extending the behaviour. RealNumbers cannot do any extra operations complex number can't do, so no point in doing this.


                • implementing abstract behaviour with a specific implementation. Since ComplexNumber should not be abstract this also does not apply.


                • code reuse. If you just use the ComplexNumber class you reuse 100% of the code.


                • more specific/efficient/accurate implementation for a specific task. This could be applied here, RealNumbers could implement some functionalities faster. But then this subclass should be hidden behind the static fromDouble(double) and should not be known outside. This way it would not need to hide the imaginary part. For the outside there should only be complex numbers (which real numbers are). You could also return this private RealNumber class from any operations in the complex number class that results in a real number. (This assumes the classes are immutable as most number classes.)


                It is like implementing a subclass of Integer that is called Zero and hardcode some of the operations since they are trivial for zero. You could do this, as every zero is an integer, but don't make it public, hide it behind a factory method.






                share|improve this answer

























                • I am not surprised to get some downvote, since I have no source to prove. Also if nobody else had an idea, I always suspect there might be some reason for that. But please tell me why you think it is wrong and how you would make it better.

                  – findusl
                  Jan 10 at 9:06















                0














                Solution: Do not have a public RealNumber class



                I would find it totally OK if ComplexNumber had a static factory method fromDouble(double) that would return a complex number with imaginary being zero. You can then use all the operations that you would use on a RealNumber instance on this ComplexNumber instance.



                But I have trouble seeing why you would want/need to have a public inherited RealNumber class. Usually inheritance is used for these reasons (out of my head, correct me if missed some)



                • extending the behaviour. RealNumbers cannot do any extra operations complex number can't do, so no point in doing this.


                • implementing abstract behaviour with a specific implementation. Since ComplexNumber should not be abstract this also does not apply.


                • code reuse. If you just use the ComplexNumber class you reuse 100% of the code.


                • more specific/efficient/accurate implementation for a specific task. This could be applied here, RealNumbers could implement some functionalities faster. But then this subclass should be hidden behind the static fromDouble(double) and should not be known outside. This way it would not need to hide the imaginary part. For the outside there should only be complex numbers (which real numbers are). You could also return this private RealNumber class from any operations in the complex number class that results in a real number. (This assumes the classes are immutable as most number classes.)


                It is like implementing a subclass of Integer that is called Zero and hardcode some of the operations since they are trivial for zero. You could do this, as every zero is an integer, but don't make it public, hide it behind a factory method.






                share|improve this answer

























                • I am not surprised to get some downvote, since I have no source to prove. Also if nobody else had an idea, I always suspect there might be some reason for that. But please tell me why you think it is wrong and how you would make it better.

                  – findusl
                  Jan 10 at 9:06













                0












                0








                0







                Solution: Do not have a public RealNumber class



                I would find it totally OK if ComplexNumber had a static factory method fromDouble(double) that would return a complex number with imaginary being zero. You can then use all the operations that you would use on a RealNumber instance on this ComplexNumber instance.



                But I have trouble seeing why you would want/need to have a public inherited RealNumber class. Usually inheritance is used for these reasons (out of my head, correct me if missed some)



                • extending the behaviour. RealNumbers cannot do any extra operations complex number can't do, so no point in doing this.


                • implementing abstract behaviour with a specific implementation. Since ComplexNumber should not be abstract this also does not apply.


                • code reuse. If you just use the ComplexNumber class you reuse 100% of the code.


                • more specific/efficient/accurate implementation for a specific task. This could be applied here, RealNumbers could implement some functionalities faster. But then this subclass should be hidden behind the static fromDouble(double) and should not be known outside. This way it would not need to hide the imaginary part. For the outside there should only be complex numbers (which real numbers are). You could also return this private RealNumber class from any operations in the complex number class that results in a real number. (This assumes the classes are immutable as most number classes.)


                It is like implementing a subclass of Integer that is called Zero and hardcode some of the operations since they are trivial for zero. You could do this, as every zero is an integer, but don't make it public, hide it behind a factory method.






                share|improve this answer















                Solution: Do not have a public RealNumber class



                I would find it totally OK if ComplexNumber had a static factory method fromDouble(double) that would return a complex number with imaginary being zero. You can then use all the operations that you would use on a RealNumber instance on this ComplexNumber instance.



                But I have trouble seeing why you would want/need to have a public inherited RealNumber class. Usually inheritance is used for these reasons (out of my head, correct me if missed some)



                • extending the behaviour. RealNumbers cannot do any extra operations complex number can't do, so no point in doing this.


                • implementing abstract behaviour with a specific implementation. Since ComplexNumber should not be abstract this also does not apply.


                • code reuse. If you just use the ComplexNumber class you reuse 100% of the code.


                • more specific/efficient/accurate implementation for a specific task. This could be applied here, RealNumbers could implement some functionalities faster. But then this subclass should be hidden behind the static fromDouble(double) and should not be known outside. This way it would not need to hide the imaginary part. For the outside there should only be complex numbers (which real numbers are). You could also return this private RealNumber class from any operations in the complex number class that results in a real number. (This assumes the classes are immutable as most number classes.)


                It is like implementing a subclass of Integer that is called Zero and hardcode some of the operations since they are trivial for zero. You could do this, as every zero is an integer, but don't make it public, hide it behind a factory method.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jan 9 at 19:21

























                answered Jan 9 at 18:39









                finduslfindusl

                1275




                1275












                • I am not surprised to get some downvote, since I have no source to prove. Also if nobody else had an idea, I always suspect there might be some reason for that. But please tell me why you think it is wrong and how you would make it better.

                  – findusl
                  Jan 10 at 9:06

















                • I am not surprised to get some downvote, since I have no source to prove. Also if nobody else had an idea, I always suspect there might be some reason for that. But please tell me why you think it is wrong and how you would make it better.

                  – findusl
                  Jan 10 at 9:06
















                I am not surprised to get some downvote, since I have no source to prove. Also if nobody else had an idea, I always suspect there might be some reason for that. But please tell me why you think it is wrong and how you would make it better.

                – findusl
                Jan 10 at 9:06





                I am not surprised to get some downvote, since I have no source to prove. Also if nobody else had an idea, I always suspect there might be some reason for that. But please tell me why you think it is wrong and how you would make it better.

                – findusl
                Jan 10 at 9:06











                0














                Saying that a real number is a complex number has more meaning in mathematics, especially set theory, than computer science.

                In mathematics we say :



                • A real number is a complex number because the set of complex numbers
                  includes the set of real numbers.

                • A rational number is a real number because the set of real numbers includes the set of rational numbers (and the set of
                  irrational numbers).

                • An integer is a rational number because the set of rational numbers includes the set of integers.

                However, this does not mean you must, or even should, use inheritance when designing your library to include a RealNumber and ComplexNumber class. In Effective Java, Second Edition by Joshua Bloch; Item 16 is "Favor Composition Over Inheritance". To avoid the problems mentioned in that item, once you have your RealNumber class defined, it can be used in your ComplexNumber class:



                public class ComplexNumber 
                private RealNumber realPart;
                private RealNumber imaginaryPart;

                // Implementation details are for you to write



                This allows you all the power of reusing your RealNumber class to keep your code DRY while avoiding the issues identified by Joshua Bloch.






                share|improve this answer



























                  0














                  Saying that a real number is a complex number has more meaning in mathematics, especially set theory, than computer science.

                  In mathematics we say :



                  • A real number is a complex number because the set of complex numbers
                    includes the set of real numbers.

                  • A rational number is a real number because the set of real numbers includes the set of rational numbers (and the set of
                    irrational numbers).

                  • An integer is a rational number because the set of rational numbers includes the set of integers.

                  However, this does not mean you must, or even should, use inheritance when designing your library to include a RealNumber and ComplexNumber class. In Effective Java, Second Edition by Joshua Bloch; Item 16 is "Favor Composition Over Inheritance". To avoid the problems mentioned in that item, once you have your RealNumber class defined, it can be used in your ComplexNumber class:



                  public class ComplexNumber 
                  private RealNumber realPart;
                  private RealNumber imaginaryPart;

                  // Implementation details are for you to write



                  This allows you all the power of reusing your RealNumber class to keep your code DRY while avoiding the issues identified by Joshua Bloch.






                  share|improve this answer

























                    0












                    0








                    0







                    Saying that a real number is a complex number has more meaning in mathematics, especially set theory, than computer science.

                    In mathematics we say :



                    • A real number is a complex number because the set of complex numbers
                      includes the set of real numbers.

                    • A rational number is a real number because the set of real numbers includes the set of rational numbers (and the set of
                      irrational numbers).

                    • An integer is a rational number because the set of rational numbers includes the set of integers.

                    However, this does not mean you must, or even should, use inheritance when designing your library to include a RealNumber and ComplexNumber class. In Effective Java, Second Edition by Joshua Bloch; Item 16 is "Favor Composition Over Inheritance". To avoid the problems mentioned in that item, once you have your RealNumber class defined, it can be used in your ComplexNumber class:



                    public class ComplexNumber 
                    private RealNumber realPart;
                    private RealNumber imaginaryPart;

                    // Implementation details are for you to write



                    This allows you all the power of reusing your RealNumber class to keep your code DRY while avoiding the issues identified by Joshua Bloch.






                    share|improve this answer













                    Saying that a real number is a complex number has more meaning in mathematics, especially set theory, than computer science.

                    In mathematics we say :



                    • A real number is a complex number because the set of complex numbers
                      includes the set of real numbers.

                    • A rational number is a real number because the set of real numbers includes the set of rational numbers (and the set of
                      irrational numbers).

                    • An integer is a rational number because the set of rational numbers includes the set of integers.

                    However, this does not mean you must, or even should, use inheritance when designing your library to include a RealNumber and ComplexNumber class. In Effective Java, Second Edition by Joshua Bloch; Item 16 is "Favor Composition Over Inheritance". To avoid the problems mentioned in that item, once you have your RealNumber class defined, it can be used in your ComplexNumber class:



                    public class ComplexNumber 
                    private RealNumber realPart;
                    private RealNumber imaginaryPart;

                    // Implementation details are for you to write



                    This allows you all the power of reusing your RealNumber class to keep your code DRY while avoiding the issues identified by Joshua Bloch.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Jan 9 at 20:07









                    Craig NoahCraig Noah

                    195




                    195





















                        0














                        There are two issues here. The first is that it's common to use the same terms for the types of containers and the types of their contents, especially with primitive types like numbers. The term double, for example, is used to describe both a double-precision floating-point value and a container in which one may be stored.



                        The second issue is that while is-a relationships among containers from which various types of objects can be read behave the same as the relationships among the objects themselves, those among containers into which various types of objects can be placed behave opposite those among their contents. Every cage that's known to hold an instance of Cat will be a cage that holds an instance of Animal, but need not be be a cage that holds an instance of SiameseCat. On the other hand, every cage that can hold all instances of Cat will be a cage that can hold all instances of SiameseCat, but need not be a cage that can hold all instances of Animal. The only kind of cage that can hold all instances of Cat and can be guaranteed never hold anything other than an instance of Cat, is a cage of Cat. Any other kind of cage would either be incapable of accepting some instances of Cat that it should accept, or would be capable of accepting things that are not instances of Cat.






                        share|improve this answer



























                          0














                          There are two issues here. The first is that it's common to use the same terms for the types of containers and the types of their contents, especially with primitive types like numbers. The term double, for example, is used to describe both a double-precision floating-point value and a container in which one may be stored.



                          The second issue is that while is-a relationships among containers from which various types of objects can be read behave the same as the relationships among the objects themselves, those among containers into which various types of objects can be placed behave opposite those among their contents. Every cage that's known to hold an instance of Cat will be a cage that holds an instance of Animal, but need not be be a cage that holds an instance of SiameseCat. On the other hand, every cage that can hold all instances of Cat will be a cage that can hold all instances of SiameseCat, but need not be a cage that can hold all instances of Animal. The only kind of cage that can hold all instances of Cat and can be guaranteed never hold anything other than an instance of Cat, is a cage of Cat. Any other kind of cage would either be incapable of accepting some instances of Cat that it should accept, or would be capable of accepting things that are not instances of Cat.






                          share|improve this answer

























                            0












                            0








                            0







                            There are two issues here. The first is that it's common to use the same terms for the types of containers and the types of their contents, especially with primitive types like numbers. The term double, for example, is used to describe both a double-precision floating-point value and a container in which one may be stored.



                            The second issue is that while is-a relationships among containers from which various types of objects can be read behave the same as the relationships among the objects themselves, those among containers into which various types of objects can be placed behave opposite those among their contents. Every cage that's known to hold an instance of Cat will be a cage that holds an instance of Animal, but need not be be a cage that holds an instance of SiameseCat. On the other hand, every cage that can hold all instances of Cat will be a cage that can hold all instances of SiameseCat, but need not be a cage that can hold all instances of Animal. The only kind of cage that can hold all instances of Cat and can be guaranteed never hold anything other than an instance of Cat, is a cage of Cat. Any other kind of cage would either be incapable of accepting some instances of Cat that it should accept, or would be capable of accepting things that are not instances of Cat.






                            share|improve this answer













                            There are two issues here. The first is that it's common to use the same terms for the types of containers and the types of their contents, especially with primitive types like numbers. The term double, for example, is used to describe both a double-precision floating-point value and a container in which one may be stored.



                            The second issue is that while is-a relationships among containers from which various types of objects can be read behave the same as the relationships among the objects themselves, those among containers into which various types of objects can be placed behave opposite those among their contents. Every cage that's known to hold an instance of Cat will be a cage that holds an instance of Animal, but need not be be a cage that holds an instance of SiameseCat. On the other hand, every cage that can hold all instances of Cat will be a cage that can hold all instances of SiameseCat, but need not be a cage that can hold all instances of Animal. The only kind of cage that can hold all instances of Cat and can be guaranteed never hold anything other than an instance of Cat, is a cage of Cat. Any other kind of cage would either be incapable of accepting some instances of Cat that it should accept, or would be capable of accepting things that are not instances of Cat.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Jan 9 at 22:35









                            supercatsupercat

                            6,9701726




                            6,9701726



























                                draft saved

                                draft discarded
















































                                Thanks for contributing an answer to Software Engineering Stack Exchange!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid


                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.

                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f385185%2fhow-to-implement-realnumber-and-complexnumber-inheritance%23new-answer', 'question_page');

                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown






                                Popular posts from this blog

                                How to check contact read email or not when send email to Individual?

                                Bahrain

                                Postfix configuration issue with fips on centos 7; mailgun relay