Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #36669 > unrolled thread

How to assign an object to another in it method?

Started byparmenides <xparmenides@yahoo.com>
First post2017-06-18 20:02 +0800
Last post2017-06-19 13:40 -0700
Articles 20 on this page of 68 — 10 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  How to assign an object to another in it method? parmenides <xparmenides@yahoo.com> - 2017-06-18 20:02 +0800
    Re: How to assign an object to another in it method? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-06-18 08:09 -0400
    Re: How to assign an object to another in it method? Robert Klemme <shortcutter@googlemail.com> - 2017-06-18 15:31 +0200
    Re: How to assign an object to another in it method? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-06-19 10:22 -0400
      Re: How to assign an object to another in it method? Eric Douglas <e.d.programmer@gmail.com> - 2017-06-19 08:13 -0700
        Re: How to assign an object to another in it method? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-06-19 11:53 -0400
          Re: How to assign an object to another in it method? Eric Douglas <e.d.programmer@gmail.com> - 2017-06-19 09:06 -0700
            Re: How to assign an object to another in it method? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-06-19 13:56 -0400
        Re: How to assign an object to another in it method? lewbloch@gmail.com - 2017-06-27 13:49 -0700
          Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-06-28 12:20 +0000
            Re: How to assign an object to another in it method? Eric Douglas <e.d.programmer@gmail.com> - 2017-06-28 05:51 -0700
              Re: How to assign an object to another in it method? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-06-28 14:03 -0400
              Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-02 21:23 -0400
                Re: How to assign an object to another in it method? Martin Gregorie <martin@address-in-sig.invalid> - 2017-07-03 10:59 +0000
                  Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-03 08:38 -0400
                    Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-07-03 14:04 +0000
                      Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-03 10:39 -0400
                        Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-07-03 16:28 +0000
                          Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-03 16:52 -0400
                      Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-03 22:04 -0400
                        Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-03 23:15 -0400
                          Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-04 21:46 -0400
                            Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-04 22:18 -0400
                              Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-08 21:13 -0400
                                Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-08 22:12 -0400
                                  Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-07-11 17:56 +0000
                                    Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-11 15:40 -0400
                                      Re: How to assign an object to another in it method? Eric Douglas <e.d.programmer@gmail.com> - 2017-07-11 13:49 -0700
                                        Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-11 17:41 -0400
                                      Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-11 20:27 -0400
                                        Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-11 21:43 -0400
                                          Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-11 21:49 -0400
                                            Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-12 17:20 -0400
                                              Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-07-13 10:08 +0000
                                                Re: How to assign an object to another in it method? Martin Gregorie <martin@address-in-sig.invalid> - 2017-07-13 11:35 +0000
                                                  Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-13 08:14 -0400
                                                    Re: How to assign an object to another in it method? Martin Gregorie <martin@address-in-sig.invalid> - 2017-07-13 14:29 +0000
                                                      Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-13 13:47 -0400
                                                        Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-07-13 18:09 +0000
                                                          Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-13 15:01 -0400
                                                            Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-07-13 19:19 +0000
                                                              Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-13 15:39 -0400
                                                  Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-07-13 16:49 +0000
                                                Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-13 10:24 -0400
                                                  Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-07-13 17:19 +0000
                                                    Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-13 21:17 -0400
                                                      Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-07-14 06:40 +0000
                                                        Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-14 14:26 -0400
                                                          Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-07-15 14:36 +0000
                                                    Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-14 12:10 -0400
                                                      Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-14 14:40 -0400
                                                        Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-14 14:51 -0400
                                                          Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-14 21:05 -0400
                                                        Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-14 21:06 -0400
                                            Re: How to assign an object to another in it method? lewbloch@gmail.com - 2017-07-14 14:44 -0700
                                          Re: How to assign an object to another in it method? Andreas Leitgeb <avl@logic.at> - 2017-07-12 16:23 +0000
                                            Re: How to assign an object to another in it method? Eric Douglas <e.d.programmer@gmail.com> - 2017-07-12 10:12 -0700
                                  Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-11 20:16 -0400
                                    Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-11 21:46 -0400
                                      Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-11 21:52 -0400
                                  Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-11 20:24 -0400
                                    Re: How to assign an object to another in it method? Jerry Stuckle <jstucklex@attglobal.net> - 2017-07-11 21:49 -0400
                                      Re: How to assign an object to another in it method? Arne Vajhøj <arne@vajhoej.dk> - 2017-07-11 21:55 -0400
                  Re: How to assign an object to another in it method? Martin Gregorie <martin@address-in-sig.invalid> - 2017-07-03 12:37 +0000
                    Re: How to assign an object to another in it method? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-07-03 11:34 -0400
                      Re: How to assign an object to another in it method? Martin Gregorie <martin@address-in-sig.invalid> - 2017-07-03 17:28 +0000
    Re: How to assign an object to another in it method? v_borchert@despammed.com (Volker Borchert) - 2017-06-19 17:13 +0000
    Re: How to assign an object to another in it method? Eric Douglas <e.d.programmer@gmail.com> - 2017-06-19 13:40 -0700

Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#36912

FromAndreas Leitgeb <avl@logic.at>
Date2017-07-13 19:19 +0000
Message-ID<slrnomfi5l.o2q.avl@logic.at>
In reply to#36911
Arne Vajhøj <arne@vajhoej.dk> wrote:
> On 7/13/2017 2:09 PM, Andreas Leitgeb wrote:
>> Arne Vajhøj <arne@vajhoej.dk> wrote:
>>> I am objecting two these two:
>>>>>>> Ideally, a subclass should be allowed to "remove" methods
>>>>>> In this case why wouldn't you override Rectangle.setDimensions() with a
>>>>>> variant that throws an exception if the two dimensions differ
>>> Sub classes should not remove functionality.
>> Maybe there's still some confusion about what "removing" means here.
> I consider overriding a method and unconditionally throw an
> exception toe be removing.

By this definition, the unmodifiableList|Set|Map wouldn't be a List|Set|Map
either...

[toc] | [prev] | [next] | [standalone]


#36913

FromArne Vajhøj <arne@vajhoej.dk>
Date2017-07-13 15:39 -0400
Message-ID<ok8i90$1732$1@gioia.aioe.org>
In reply to#36912
On 7/13/2017 3:19 PM, Andreas Leitgeb wrote:
> Arne Vajhøj <arne@vajhoej.dk> wrote:
>> On 7/13/2017 2:09 PM, Andreas Leitgeb wrote:
>>> Arne Vajhøj <arne@vajhoej.dk> wrote:
>>>> I am objecting two these two:
>>>>>>>> Ideally, a subclass should be allowed to "remove" methods
>>>>>>> In this case why wouldn't you override Rectangle.setDimensions() with a
>>>>>>> variant that throws an exception if the two dimensions differ
>>>> Sub classes should not remove functionality.
>>> Maybe there's still some confusion about what "removing" means here.
>> I consider overriding a method and unconditionally throw an
>> exception toe be removing.
> 
> By this definition, the unmodifiableList|Set|Map wouldn't be a List|Set|Map
> either...

That could also be considered dubious.

But it is somewhat different.

Map is not a class but an interface, so it has no functionality to
remove (except the recently added default methods) only a contract
and the documentation of that contract clearly states that it
may throw an exception if the operation is not supported by the
implementation.

Then of course there are AbstractMap but that is more of a
code reuse thingy than a real thingy.

Arne

[toc] | [prev] | [next] | [standalone]


#36900

FromAndreas Leitgeb <avl@logic.at>
Date2017-07-13 16:49 +0000
Message-ID<slrnomf9cm.o2q.avl@logic.at>
In reply to#36881
Martin Gregorie <martin@address-in-sig.invalid> wrote:
> On Thu, 13 Jul 2017 10:08:52 +0000, Andreas Leitgeb wrote:
>> Ideally, a subclass should be allowed to "remove" methods in a way that
>> the compiler could preempt some mistakes: "If you already know you're
>> dealing with a Square, then rather use Square's setDimension(int length)
>> instead of the inherited setDimensions(int,int)".  Obviously the compiler
>> couldn't catch cases like ((Rectangle)square).setDimensions(1,2), so not
>> all runtime errors can be prevented at compile time, but at least some.
> In this case why wouldn't you override Rectangle.setDimensions() with a 
> variant that throws an exception if the two dimensions differ

Because such an exception would only be thrown at runtime. 

My aim is to help the compiler find bugs ahead of time in as many as
feasible cases.  At this time, there just doesn't seem to be a way
to prevent a call like "square.setDimensions( i1, i2 );" already at
compile time.

One could perhaps tag it as @Deprecated, but that'll only lead to
a compile time warning, not an error. (I haven't tried it, though)


Imho, it is not a violation of "is-a", if a subclass declares 
some base-class's method as "not applicable" to this specialization.

An unmodifiable Set is still a Set.  But rather than saying
  "Come on, try to modify me and see if I care!"
it could preferably say
  "Hey, you *know* I'm unmodifiable! Don't you even *try*!"
(and where the caller *doesn't* know, only *then* callee would
fall back to throwing an exception at runtime)

[toc] | [prev] | [next] | [standalone]


#36892

FromJerry Stuckle <jstucklex@attglobal.net>
Date2017-07-13 10:24 -0400
Message-ID<ok7vjd$uef$1@jstuckle.eternal-september.org>
In reply to#36877
On 7/13/2017 6:08 AM, Andreas Leitgeb wrote:
> Jerry Stuckle <jstucklex@attglobal.net> wrote:
>> On 7/11/2017 9:49 PM, Arne Vajhøj wrote:
>>> My post does not contain "valid values".
>>> Your post containa "valid values".
>> Sorry, you are correct.  It was Andreas who brought up the default
>> values.  My mistake - I didn't read closely enough.
> 
> The sub-topic of "default values" was what triggered me into entering 
> the discussion.  I brought up the problem(imho) of overriding methods with
> changed default values for arguments, which in C++ are static type matter
> (non-polymorphic).
>

Incorrect.  Methods with default values are also polymorphic.

> Apparently this triggered someone else to think that if I even want to 
> use a different default value in the override, then "obviously" the
> original would necessarily be inappropriate or "invalid" for the subclass.
> 

It is possible for the default value in a base class to be invalid in
the derived class.  But correctly designed, that should not be a problem.

> I think that's how validity entered this thread.
> 
> PS: my Manager/Employee adaption did not yet have a minimumWage constraint.
>   If it had one, then Manager would probably have a "more constraining" one.
>   I.e.: his minimum wage would be even higher. (Assuming that the Manager
>   is still an Employee, too, and not already the owner of the company.)
> 
> Going back to Java and the Rectangle/Square example: What would be
> Square's appropriate way to deal with the setDimensions(int height,int width)
> inherited from Rectangle?  Apparently it would need to still offer it and
> thus introduce a new potential for runtime-errors with currently no way to
> have already the compiler warn about "square.setDimensions(1,2)" being fishy.
> 

That can be a problem with inheritance, and one with no perfect
solution.  One way would be to not derive one from the other, but would
derive both from a Shape class.  Another way would be to provide a
runtime error.

> Ideally, a subclass should be allowed to "remove" methods in a way that the
> compiler could preempt some mistakes: "If you already know you're dealing
> with a Square, then rather use Square's setDimension(int length) instead of
> the inherited setDimension(int,int)".  Obviously the compiler couldn't catch
> cases like ((Rectangle)square).setDimensions(1,2), so not all runtime
> errors can be prevented at compile time, but at least some.
> 

So what happens when you pass the derived object to a method expecting a
base object?

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

[toc] | [prev] | [next] | [standalone]


#36902

FromAndreas Leitgeb <avl@logic.at>
Date2017-07-13 17:19 +0000
Message-ID<slrnomfb4t.o2q.avl@logic.at>
In reply to#36892
Jerry Stuckle <jstucklex@attglobal.net> wrote:
> On 7/13/2017 6:08 AM, Andreas Leitgeb wrote:
>> I brought up the problem(imho) of overriding methods with
>> changed default values for arguments, which in C++ are static
>> type matter (non-polymorphic).
> Incorrect.  Methods with default values are also polymorphic.

#include <stdio.h>

struct A { virtual void foo(int i = 42) { printf("A: %d\n", i); } };
struct B : public A { void foo(int i = 54) { printf("B: %d\n", i); } };

int main() {
      A a;  a.foo();
      B b;  b.foo();
      A *pa = &a;  pa->foo();
      pa = &b;     pa->foo();
}

Compiling and running it yields:
A: 42
B: 54
A: 42
B: 42

The last one polymorphically(because of the 'virtual') calls B::foo(int),
but passss it A::foo's default value, as the pointer is A-typed.

So, I still consider my claim as correct.

>> Ideally, a subclass should be allowed to "remove" methods in a way that the
>> compiler could preempt some mistakes: "If you already know you're dealing
>> with a Square, then rather use Square's setDimension(int length) instead of
>> the inherited setDimension(int,int)".  Obviously the compiler couldn't catch
>> cases like ((Rectangle)square).setDimensions(1,2), so not all runtime
>> errors can be prevented at compile time, but at least some.
>
> So what happens when you pass the derived object to a method expecting a
> base object?

Then it would end up running that "disabled" method, which will do whatever
is coded into it:  e.g. always throw an error, or spend some effort to
determine still-sensible calls, for which to do something sensible.

In C++ you can declare an override as private - if it was virtual within
the super class, it can still be called through super class, but not through
its own type.

In the example above, add a "private:" into B's body before void foo...,
and since the b.foo() call becomes invalid, comment it out. The last call
will still invoke the now private B::foo (and still with 42 as default).

I don't like the non-polymorphic default values of C++, but I do like that
in C++ a subclass *can* get rid of its inherited baggage.

[toc] | [prev] | [next] | [standalone]


#36922

FromArne Vajhøj <arne@vajhoej.dk>
Date2017-07-13 21:17 -0400
Message-ID<ok9644$1vrm$1@gioia.aioe.org>
In reply to#36902
On 7/13/2017 1:19 PM, Andreas Leitgeb wrote:
> Jerry Stuckle <jstucklex@attglobal.net> wrote:
>> On 7/13/2017 6:08 AM, Andreas Leitgeb wrote:
>>> I brought up the problem(imho) of overriding methods with
>>> changed default values for arguments, which in C++ are static
>>> type matter (non-polymorphic).
>> Incorrect.  Methods with default values are also polymorphic.
> 
> #include <stdio.h>
> 
> struct A { virtual void foo(int i = 42) { printf("A: %d\n", i); } };
> struct B : public A { void foo(int i = 54) { printf("B: %d\n", i); } };
> 
> int main() {
>        A a;  a.foo();
>        B b;  b.foo();
>        A *pa = &a;  pa->foo();
>        pa = &b;     pa->foo();
> }
> 
> Compiling and running it yields:
> A: 42
> B: 54
> A: 42
> B: 42
> 
> The last one polymorphically(because of the 'virtual') calls B::foo(int),
> but passss it A::foo's default value, as the pointer is A-typed.
> 
> So, I still consider my claim as correct.

You are correct that even virtual call change behavior
depending on type of the pointer when default values are
applied.

I would code the example a bit different:

#include <iostream>

using namespace std;

class P
{
public:
     void virtual foo(int v = 123) { cout << v << endl; }
};

class C : public P
{
public:
     void virtual foo(int v = 456) { P::foo(v); }
     void virtual bar() { cout << "Hi" << endl; }
};

int main()
{
     // old code
     P *o1 = new C();
     o1->foo();
     // new code
     C *o2 = new C();
     o2->bar();
     o2->foo();
     //
     return 0;
}

But it shows the same thing.

P *o1 = new C(); vs C *o2 = new C(); changes the behavior of the foo 
call. Aka non-polymorphic behavior for a virtual method.

But:
- you would get the same effect without default values for non-virtual 
methods
- how do you know that the method is virtual without noticing the 
default values?

Arne

[toc] | [prev] | [next] | [standalone]


#36925

FromAndreas Leitgeb <avl@logic.at>
Date2017-07-14 06:40 +0000
Message-ID<slrnomgq2b.o2q.avl@logic.at>
In reply to#36922
Arne Vajhøj <arne@vajhoej.dk> wrote:
> But it shows the same thing.
> [...]
> But:
> - you would get the same effect without default values for non-virtual 
> methods

default values in C++ are not polymorphic, so, indeed, it
would seem consistent with non-polymorphic (non-virtual)
methods.


> - how do you know that the method is virtual without noticing the 
> default values?

by letting the override do something observably different,
as my own example did.

[toc] | [prev] | [next] | [standalone]


#36933

FromArne Vajhøj <arne@vajhoej.dk>
Date2017-07-14 14:26 -0400
Message-ID<okb2cq$k3p$1@gioia.aioe.org>
In reply to#36925
On 7/14/2017 2:40 AM, Andreas Leitgeb wrote:
> Arne Vajhøj <arne@vajhoej.dk> wrote:
>> But it shows the same thing.
>> [...]
>> But:
>> - you would get the same effect without default values for non-virtual
>> methods
> 
> default values in C++ are not polymorphic, so, indeed, it
> would seem consistent with non-polymorphic (non-virtual)
> methods.
> 
>> - how do you know that the method is virtual without noticing the
>> default values?
> 
> by letting the override do something observably different,
> as my own example did.

Let me try to explain better what I mean.

A developer is writing some code and has to decide between:

P *o = new C();

and:

C *o = new C();

The developer wants C behavior for o, which requires polymorphic
behavior for the first option to be viable.

Non virtual methods are not polymorphic, so the developer need to
check which methods are virtual and which are non virtual.

Is that check possible to do without as a side effect to also
note the default values?

Arne

[toc] | [prev] | [next] | [standalone]


#36949

FromAndreas Leitgeb <avl@logic.at>
Date2017-07-15 14:36 +0000
Message-ID<slrnomkaaq.o2q.avl@logic.at>
In reply to#36933
Arne Vajhøj <arne@vajhoej.dk> wrote:
> On 7/14/2017 2:40 AM, Andreas Leitgeb wrote:
>> Arne Vajhøj <arne@vajhoej.dk> wrote:
>>> - how do you know that the method is virtual without noticing the
>>> default values?
>> by letting the override do something observably different,
>> as my own example did.
> Let me try to explain better what I mean.
> A developer is writing some code and has to decide between:
>   P *o = new C();
> and:
>   C *o = new C();

This decision should be guided primarily by these thoughts:
 - will I need to access (class) C-specific methods or attributes?
     -> then go for "C" for the pointer.
 - is it likely that o will need to point to a non-C object?
     (or likely in future by foreseeable further development?)
     -> then go for "P" for the pointer.

This decision shouldn't depend on whether P has non-virtual methods
or uses (non-polymorphic) defaults for some method arguments, just
because the decision of designing for polymorphism (or not) should 
depend on how it is meant to be used.

If developer finds out they need polymorphic behaviour, they'd better
dump the default values, and use a a second (also virtual) method
with the simpler signature that will call the other version with
a value...

   struct P {
      virtual void foo(int i = 42) { ... }
   }
would then (iff needed) just be changed to:
   struct P {
      virtual void foo(int i) { ... }
      virtual void foo() { foo(42); }
   }

and any subclass can decide to overriding the " default " and/or
the actual implementation, independently. (Surprise: that's just
how you would do it in Java, too, except for the exact syntax.)

> The developer wants C behavior for o, which requires polymorphic
> behavior for the first option to be viable.

If they only needs C behaviour, he'll just pick "C" for pointer's type
and be set.  If he polymorphically needs C or D behaviour, he had 
better use classes C and D that are suitably designed for the task.
(or just design C and D suitable for the task, themself.)

> Non virtual methods are not polymorphic, so the developer need to
> check which methods are virtual and which are non virtual.

Check... in the documentation (or source) ?
I hope you don't mean that they would hack some test program just
to see if the method is declared virtual or not, or that they would
expect to draw any conclusions based on what value the method ends
up seeing.

> Is that check possible to do without as a side effect to also
> note the default values?

You lost me here (or already long before).

[toc] | [prev] | [next] | [standalone]


#36929

FromJerry Stuckle <jstucklex@attglobal.net>
Date2017-07-14 12:10 -0400
Message-ID<okaq5e$6et$1@jstuckle.eternal-september.org>
In reply to#36902
On 7/13/2017 1:19 PM, Andreas Leitgeb wrote:
> Jerry Stuckle <jstucklex@attglobal.net> wrote:
>> On 7/13/2017 6:08 AM, Andreas Leitgeb wrote:
>>> I brought up the problem(imho) of overriding methods with
>>> changed default values for arguments, which in C++ are static
>>> type matter (non-polymorphic).
>> Incorrect.  Methods with default values are also polymorphic.
> 
> #include <stdio.h>
> 
> struct A { virtual void foo(int i = 42) { printf("A: %d\n", i); } };
> struct B : public A { void foo(int i = 54) { printf("B: %d\n", i); } };
> 
> int main() {
>       A a;  a.foo();
>       B b;  b.foo();
>       A *pa = &a;  pa->foo();
>       pa = &b;     pa->foo();
> }
> 
> Compiling and running it yields:
> A: 42
> B: 54
> A: 42
> B: 42
> 
> The last one polymorphically(because of the 'virtual') calls B::foo(int),
> but passss it A::foo's default value, as the pointer is A-typed.
> 
> So, I still consider my claim as correct.
> 
>>> Ideally, a subclass should be allowed to "remove" methods in a way that the
>>> compiler could preempt some mistakes: "If you already know you're dealing
>>> with a Square, then rather use Square's setDimension(int length) instead of
>>> the inherited setDimension(int,int)".  Obviously the compiler couldn't catch
>>> cases like ((Rectangle)square).setDimensions(1,2), so not all runtime
>>> errors can be prevented at compile time, but at least some.
>>
>> So what happens when you pass the derived object to a method expecting a
>> base object?
> 
> Then it would end up running that "disabled" method, which will do whatever
> is coded into it:  e.g. always throw an error, or spend some effort to
> determine still-sensible calls, for which to do something sensible.
> 
> In C++ you can declare an override as private - if it was virtual within
> the super class, it can still be called through super class, but not through
> its own type.
> 
> In the example above, add a "private:" into B's body before void foo...,
> and since the b.foo() call becomes invalid, comment it out. The last call
> will still invoke the now private B::foo (and still with 42 as default).
> 
> I don't like the non-polymorphic default values of C++, but I do like that
> in C++ a subclass *can* get rid of its inherited baggage.
> 

Interesting - I hadn't run into this before (probably because I don't
use a lot of default arguments in virtual functions).  It did take some
looking but I finally found the part of the standard which covers this:

In 11.3.6 Paragraph 10:

"A virtual function call (13.3) uses the default arguments in the
declaration of the virtual function determined by the static type of the
pointer or reference denoting the object. An overriding function in a
derived class does not acquire default arguments from the function it
overrides."

The more I think of this the more sense it makes (although I don't like
it).  Default arguments are inserted at compile time, not run time.  So
it would have to use the static type of the pointer or reference.  I do
think it should be possible to make that determination at runtime,
though. But that is also off-topic in this newsgroup.

I do appreciate, however, you correcting me on this point.

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

[toc] | [prev] | [next] | [standalone]


#36934

FromArne Vajhøj <arne@vajhoej.dk>
Date2017-07-14 14:40 -0400
Message-ID<okb37k$l8q$1@gioia.aioe.org>
In reply to#36929
On 7/14/2017 12:10 PM, Jerry Stuckle wrote:
> On 7/13/2017 1:19 PM, Andreas Leitgeb wrote:
>> I don't like the non-polymorphic default values of C++, but I do like that
>> in C++ a subclass *can* get rid of its inherited baggage.
> 
> Interesting - I hadn't run into this before (probably because I don't
> use a lot of default arguments in virtual functions).  It did take some
> looking but I finally found the part of the standard which covers this:
> 
> In 11.3.6 Paragraph 10:
> 
> "A virtual function call (13.3) uses the default arguments in the
> declaration of the virtual function determined by the static type of the
> pointer or reference denoting the object. An overriding function in a
> derived class does not acquire default arguments from the function it
> overrides."
> 
> The more I think of this the more sense it makes (although I don't like
> it).  Default arguments are inserted at compile time, not run time.  So
> it would have to use the static type of the pointer or reference.  I do
> think it should be possible to make that determination at runtime,
> though.

It may be worth noting that C# does it the same way.

using System;

namespace E
{
     public class P
     {
         public virtual void Foo(int v = 123)
         {
             Console.WriteLine(v);
         }
     }
     public class C : P
     {
         public override void Foo(int v = 456)
         {
             base.Foo(v);
         }
     }
     public class Program
     {
         public static void Main(string[] args)
         {
             P o1 = new C();
             o1.Foo();
             C o2 = new C();
             o2.Foo();
             Console.ReadKey();
         }
     }
}

outputs:

123
456

Arne

[toc] | [prev] | [next] | [standalone]


#36936

FromJerry Stuckle <jstucklex@attglobal.net>
Date2017-07-14 14:51 -0400
Message-ID<okb3j1$4o4$1@jstuckle.eternal-september.org>
In reply to#36934
On 7/14/2017 2:40 PM, Arne Vajhøj wrote:
> On 7/14/2017 12:10 PM, Jerry Stuckle wrote:
>> On 7/13/2017 1:19 PM, Andreas Leitgeb wrote:
>>> I don't like the non-polymorphic default values of C++, but I do like
>>> that
>>> in C++ a subclass *can* get rid of its inherited baggage.
>>
>> Interesting - I hadn't run into this before (probably because I don't
>> use a lot of default arguments in virtual functions).  It did take some
>> looking but I finally found the part of the standard which covers this:
>>
>> In 11.3.6 Paragraph 10:
>>
>> "A virtual function call (13.3) uses the default arguments in the
>> declaration of the virtual function determined by the static type of the
>> pointer or reference denoting the object. An overriding function in a
>> derived class does not acquire default arguments from the function it
>> overrides."
>>
>> The more I think of this the more sense it makes (although I don't like
>> it).  Default arguments are inserted at compile time, not run time.  So
>> it would have to use the static type of the pointer or reference.  I do
>> think it should be possible to make that determination at runtime,
>> though.
> 
> It may be worth noting that C# does it the same way.
> 
> using System;
> 
> namespace E
> {
>     public class P
>     {
>         public virtual void Foo(int v = 123)
>         {
>             Console.WriteLine(v);
>         }
>     }
>     public class C : P
>     {
>         public override void Foo(int v = 456)
>         {
>             base.Foo(v);
>         }
>     }
>     public class Program
>     {
>         public static void Main(string[] args)
>         {
>             P o1 = new C();
>             o1.Foo();
>             C o2 = new C();
>             o2.Foo();
>             Console.ReadKey();
>         }
>     }
> }
> 
> outputs:
> 
> 123
> 456
> 
> Arne

Who cares about Microsoft crap?

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

[toc] | [prev] | [next] | [standalone]


#36944

FromArne Vajhøj <arne@vajhoej.dk>
Date2017-07-14 21:05 -0400
Message-ID<okbpo5$1hk5$1@gioia.aioe.org>
In reply to#36936
On 7/14/2017 2:51 PM, Jerry Stuckle wrote:
> On 7/14/2017 2:40 PM, Arne Vajhøj wrote:
>> On 7/14/2017 12:10 PM, Jerry Stuckle wrote:
>>> On 7/13/2017 1:19 PM, Andreas Leitgeb wrote:
>>>> I don't like the non-polymorphic default values of C++, but I do like
>>>> that
>>>> in C++ a subclass *can* get rid of its inherited baggage.
>>>
>>> Interesting - I hadn't run into this before (probably because I don't
>>> use a lot of default arguments in virtual functions).  It did take some
>>> looking but I finally found the part of the standard which covers this:
>>>
>>> In 11.3.6 Paragraph 10:
>>>
>>> "A virtual function call (13.3) uses the default arguments in the
>>> declaration of the virtual function determined by the static type of the
>>> pointer or reference denoting the object. An overriding function in a
>>> derived class does not acquire default arguments from the function it
>>> overrides."
>>>
>>> The more I think of this the more sense it makes (although I don't like
>>> it).  Default arguments are inserted at compile time, not run time.  So
>>> it would have to use the static type of the pointer or reference.  I do
>>> think it should be possible to make that determination at runtime,
>>> though.
>>
>> It may be worth noting that C# does it the same way.
>>
>> using System;
>>
>> namespace E
>> {
>>      public class P
>>      {
>>          public virtual void Foo(int v = 123)
>>          {
>>              Console.WriteLine(v);
>>          }
>>      }
>>      public class C : P
>>      {
>>          public override void Foo(int v = 456)
>>          {
>>              base.Foo(v);
>>          }
>>      }
>>      public class Program
>>      {
>>          public static void Main(string[] args)
>>          {
>>              P o1 = new C();
>>              o1.Foo();
>>              C o2 = new C();
>>              o2.Foo();
>>              Console.ReadKey();
>>          }
>>      }
>> }
>>
>> outputs:
>>
>> 123
>> 456
> 
> Who cares about Microsoft crap?

Those using it.

:-)

Arne

[toc] | [prev] | [next] | [standalone]


#36945

FromArne Vajhøj <arne@vajhoej.dk>
Date2017-07-14 21:06 -0400
Message-ID<okbpqa$1hk5$2@gioia.aioe.org>
In reply to#36934
On 7/14/2017 2:40 PM, Arne Vajhøj wrote:
> On 7/14/2017 12:10 PM, Jerry Stuckle wrote:
>> On 7/13/2017 1:19 PM, Andreas Leitgeb wrote:
>>> I don't like the non-polymorphic default values of C++, but I do like 
>>> that
>>> in C++ a subclass *can* get rid of its inherited baggage.
>>
>> Interesting - I hadn't run into this before (probably because I don't
>> use a lot of default arguments in virtual functions).  It did take some
>> looking but I finally found the part of the standard which covers this:
>>
>> In 11.3.6 Paragraph 10:
>>
>> "A virtual function call (13.3) uses the default arguments in the
>> declaration of the virtual function determined by the static type of the
>> pointer or reference denoting the object. An overriding function in a
>> derived class does not acquire default arguments from the function it
>> overrides."
>>
>> The more I think of this the more sense it makes (although I don't like
>> it).  Default arguments are inserted at compile time, not run time.  So
>> it would have to use the static type of the pointer or reference.  I do
>> think it should be possible to make that determination at runtime,
>> though.
> 
> It may be worth noting that C# does it the same way.

Kotlin is different.

 From documentation:

<quote>
Overriding methods always use the same default parameter values as the 
base method. When overriding a method with default parameters values, 
the default parameter values must be omitted from the signature
</quote>

Arne

[toc] | [prev] | [next] | [standalone]


#36941

Fromlewbloch@gmail.com
Date2017-07-14 14:44 -0700
Message-ID<e3ffc0b5-44f9-4dbc-96bf-1b11b9a85833@googlegroups.com>
In reply to#36858
The problem with wrestling with a pig is that you get dirty, and besides, the pig likes it. (GB Shaw, paraphrased)

[toc] | [prev] | [next] | [standalone]


#36865

FromAndreas Leitgeb <avl@logic.at>
Date2017-07-12 16:23 +0000
Message-ID<slrnomcjfv.o2q.avl@logic.at>
In reply to#36855
Jerry Stuckle <jstucklex@attglobal.net> wrote:
> Nope.  In the strictest sense is is NOT a valid derived class.  The
> rules given for Employee were that wage must be >= minimum wage.  The
> rules for Manager do not include that restriction.  Therefore it is an
> invalid inheritance - no matter what you name them.

Welcome to the topic of covariant versus contravariant types.

If I have a square (e.g. a unit square), then this square *is*
also *a* rectangle.

If I have a class Rectangle and a class Square, then Square
is a subclass of Rectangle (as every square is obviously also 
a rectangle). But then  Rectange  may have a method to *set*
both side lengths. But Square would not allow to set two
different lengths.

Question: is a Square a Rectangle, or is a Rectange a Square?
Answer: depends...

PS: that's also why Java generics offer <T super S> for certain uses.

[toc] | [prev] | [next] | [standalone]


#36868

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-07-12 10:12 -0700
Message-ID<8c083db2-f205-487b-ab62-ffb701fa2b25@googlegroups.com>
In reply to#36865
On Wednesday, July 12, 2017 at 12:28:02 PM UTC-4, Andreas Leitgeb wrote:
> Welcome to the topic of covariant versus contravariant types.
> 
> If I have a square (e.g. a unit square), then this square *is*
> also *a* rectangle.
> 
> If I have a class Rectangle and a class Square, then Square
> is a subclass of Rectangle (as every square is obviously also 
> a rectangle). But then  Rectange  may have a method to *set*
> both side lengths. But Square would not allow to set two
> different lengths.
> 
> Question: is a Square a Rectangle, or is a Rectange a Square?
> Answer: depends...
> 
> PS: that's also why Java generics offer <T super S> for certain uses.

Isn't that the point?  Every subclass may only add validation, must not exclude validation from it's super.
Every Tiger is a Cat but not every Cat is a Tiger, therefore Tiger extends Cat, as Cat extends Animal.
Dog also extends Animal and does not need to meet the validation of Cat, whereas Dog and Cat may optionally meet the validation of interface Fluffy.

[toc] | [prev] | [next] | [standalone]


#36851

FromArne Vajhøj <arne@vajhoej.dk>
Date2017-07-11 20:16 -0400
Message-ID<ok3ppi$j6k$1@gioia.aioe.org>
In reply to#36842
On 7/8/2017 10:12 PM, Jerry Stuckle wrote:
> On 7/8/2017 9:13 PM, Arne Vajhøj wrote:
>> On 7/4/2017 10:18 PM, Jerry Stuckle wrote:
>>> On 7/4/2017 9:46 PM, Arne Vajhøj wrote:
>>>> On 7/3/2017 11:15 PM, Jerry Stuckle wrote:
>>>>> On 7/3/2017 10:04 PM, Arne Vajhøj wrote:
>>>>>> I hope that a static code analysis tool create warnings
>>>>>> about doing something like that.
>>>>>
>>>>> Why should they, Arne?  Default values are just that - values used when
>>>>> no others are given.  They are not the only valid values, and are there
>>>>> to be overridden.
>>>>
>>>> It indicates that the author of the super class and the author of the
>>>> sub class seems to disagree on at least one aspect of how the method
>>>> should be. That is something that should always be examined. Do the
>>>> classes really reflect an "is a" relation or is the difference a
>>>> symptom of a bigger difference/problem.
>>
>>> If that is the case, then the author of the superclass didn't design it
>>> properly.  Default values are not there to indicate the only valid
>>> values for a class.  They are there to allow for some (or all) values to
>>> be assumed.
>>>
>>> If there is a restriction in what the values can be, then that needs to
>>> be in the appropriate function.  Otherwise, there is no restriction.
>>
>> Yes. But the topic was not valid values but default values.
> 
> That is correct.  And while the default values will be valid, if there
> are restrictions on non-default values those go in the function.
> 
>>> If the subclass does not reflect an "is-a" relationship, that is a
>>> design problem which has nothing to do with default values.
>>
>> If it is the default values that break the "is a" then it has
>> something to do with it.
>>
> 
> No, values don't break an is-a relationship.  If the default values do,
> then you have an invalid relationship in the first place.

It is rather simple English.

Type X is feature set X with a default value of A.

Type Y is a feature set of X + Y with a default value of B.

Y "is a" X is false.

Y "is almost a" X is true.

>>> The bottom line here is - none of your arguments are related to the
>>> presence or absence of default arguments.  All can occur either with or
>>> without default arguments.
>>
>> My argument relates specifically to different default values, so
>> it can not happen without default arguments.
> 
> I stand by my statement.

Given that the argument above very clearly relates to "default value"
then you are proven wrong.

>                          Default values in a derived class which are
> not valid for the base class indicates an invalid relationship in the
> first place.

Yes. But that is a straw man argument because my reasons do
not relate to valid values at all.

> I would like to see an example of a valid relationship where your
> default values cause a problem.

It is obvious that there is a problem with "is a".

It could be totally harmless.

Or it could be a good indication of a problem.

It would be worth investigating what it is.

Arne

[toc] | [prev] | [next] | [standalone]


#36856

FromJerry Stuckle <jstucklex@attglobal.net>
Date2017-07-11 21:46 -0400
Message-ID<ok3ups$e2d$1@jstuckle.eternal-september.org>
In reply to#36851
On 7/11/2017 8:16 PM, Arne Vajhøj wrote:
> On 7/8/2017 10:12 PM, Jerry Stuckle wrote:
>> On 7/8/2017 9:13 PM, Arne Vajhøj wrote:
>>> On 7/4/2017 10:18 PM, Jerry Stuckle wrote:
>>>> On 7/4/2017 9:46 PM, Arne Vajhøj wrote:
>>>>> On 7/3/2017 11:15 PM, Jerry Stuckle wrote:
>>>>>> On 7/3/2017 10:04 PM, Arne Vajhøj wrote:
>>>>>>> I hope that a static code analysis tool create warnings
>>>>>>> about doing something like that.
>>>>>>
>>>>>> Why should they, Arne?  Default values are just that - values used
>>>>>> when
>>>>>> no others are given.  They are not the only valid values, and are
>>>>>> there
>>>>>> to be overridden.
>>>>>
>>>>> It indicates that the author of the super class and the author of the
>>>>> sub class seems to disagree on at least one aspect of how the method
>>>>> should be. That is something that should always be examined. Do the
>>>>> classes really reflect an "is a" relation or is the difference a
>>>>> symptom of a bigger difference/problem.
>>>
>>>> If that is the case, then the author of the superclass didn't design it
>>>> properly.  Default values are not there to indicate the only valid
>>>> values for a class.  They are there to allow for some (or all)
>>>> values to
>>>> be assumed.
>>>>
>>>> If there is a restriction in what the values can be, then that needs to
>>>> be in the appropriate function.  Otherwise, there is no restriction.
>>>
>>> Yes. But the topic was not valid values but default values.
>>
>> That is correct.  And while the default values will be valid, if there
>> are restrictions on non-default values those go in the function.
>>
>>>> If the subclass does not reflect an "is-a" relationship, that is a
>>>> design problem which has nothing to do with default values.
>>>
>>> If it is the default values that break the "is a" then it has
>>> something to do with it.
>>>
>>
>> No, values don't break an is-a relationship.  If the default values do,
>> then you have an invalid relationship in the first place.
> 
> It is rather simple English.
> 
> Type X is feature set X with a default value of A.
> 
> Type Y is a feature set of X + Y with a default value of B.
> 
> Y "is a" X is false.
> 
> Y "is almost a" X is true.
> 
>>>> The bottom line here is - none of your arguments are related to the
>>>> presence or absence of default arguments.  All can occur either with or
>>>> without default arguments.
>>>
>>> My argument relates specifically to different default values, so
>>> it can not happen without default arguments.
>>
>> I stand by my statement.
> 
> Given that the argument above very clearly relates to "default value"
> then you are proven wrong.
> 
>>                          Default values in a derived class which are
>> not valid for the base class indicates an invalid relationship in the
>> first place.
> 
> Yes. But that is a straw man argument because my reasons do
> not relate to valid values at all.
> 
>> I would like to see an example of a valid relationship where your
>> default values cause a problem.
> 
> It is obvious that there is a problem with "is a".
> 
> It could be totally harmless.
> 
> Or it could be a good indication of a problem.
> 
> It would be worth investigating what it is.
> 
> Arne
> 
> 

No, you said the default value for the derived class may be invalid for
the base class.  Therefore the inheritance would be invalid.  It is a
definite indication of a problem.

In a valid hierarchy, derived classes are always more specialized cases
of their base classes.  In a case like this you can limit the wage in
the derived class (Manager), but must stay within range of the base
class (Employee).  A value in Manager that is not valid in Employee
indicates an invalid inheritance.

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

[toc] | [prev] | [next] | [standalone]


#36859

FromArne Vajhøj <arne@vajhoej.dk>
Date2017-07-11 21:52 -0400
Message-ID<ok3vcq$o5g$2@gioia.aioe.org>
In reply to#36856
On 7/11/2017 9:46 PM, Jerry Stuckle wrote:
> On 7/11/2017 8:16 PM, Arne Vajhøj wrote:
>> On 7/8/2017 10:12 PM, Jerry Stuckle wrote:
>>> On 7/8/2017 9:13 PM, Arne Vajhøj wrote:
>>>> On 7/4/2017 10:18 PM, Jerry Stuckle wrote:
>>>>> On 7/4/2017 9:46 PM, Arne Vajhøj wrote:
>>>>>> On 7/3/2017 11:15 PM, Jerry Stuckle wrote:
>>>>>>> On 7/3/2017 10:04 PM, Arne Vajhøj wrote:
>>>>>>>> I hope that a static code analysis tool create warnings
>>>>>>>> about doing something like that.
>>>>>>>
>>>>>>> Why should they, Arne?  Default values are just that - values used
>>>>>>> when
>>>>>>> no others are given.  They are not the only valid values, and are
>>>>>>> there
>>>>>>> to be overridden.
>>>>>>
>>>>>> It indicates that the author of the super class and the author of the
>>>>>> sub class seems to disagree on at least one aspect of how the method
>>>>>> should be. That is something that should always be examined. Do the
>>>>>> classes really reflect an "is a" relation or is the difference a
>>>>>> symptom of a bigger difference/problem.
>>>>
>>>>> If that is the case, then the author of the superclass didn't design it
>>>>> properly.  Default values are not there to indicate the only valid
>>>>> values for a class.  They are there to allow for some (or all)
>>>>> values to
>>>>> be assumed.
>>>>>
>>>>> If there is a restriction in what the values can be, then that needs to
>>>>> be in the appropriate function.  Otherwise, there is no restriction.
>>>>
>>>> Yes. But the topic was not valid values but default values.
>>>
>>> That is correct.  And while the default values will be valid, if there
>>> are restrictions on non-default values those go in the function.
>>>
>>>>> If the subclass does not reflect an "is-a" relationship, that is a
>>>>> design problem which has nothing to do with default values.
>>>>
>>>> If it is the default values that break the "is a" then it has
>>>> something to do with it.
>>>>
>>>
>>> No, values don't break an is-a relationship.  If the default values do,
>>> then you have an invalid relationship in the first place.
>>
>> It is rather simple English.
>>
>> Type X is feature set X with a default value of A.
>>
>> Type Y is a feature set of X + Y with a default value of B.
>>
>> Y "is a" X is false.
>>
>> Y "is almost a" X is true.
>>
>>>>> The bottom line here is - none of your arguments are related to the
>>>>> presence or absence of default arguments.  All can occur either with or
>>>>> without default arguments.
>>>>
>>>> My argument relates specifically to different default values, so
>>>> it can not happen without default arguments.
>>>
>>> I stand by my statement.
>>
>> Given that the argument above very clearly relates to "default value"
>> then you are proven wrong.
>>
>>>                           Default values in a derived class which are
>>> not valid for the base class indicates an invalid relationship in the
>>> first place.
>>
>> Yes. But that is a straw man argument because my reasons do
>> not relate to valid values at all.
>>
>>> I would like to see an example of a valid relationship where your
>>> default values cause a problem.
>>
>> It is obvious that there is a problem with "is a".
>>
>> It could be totally harmless.
>>
>> Or it could be a good indication of a problem.
>>
>> It would be worth investigating what it is.
> 
> No, you said the default value for the derived class may be invalid for
> the base class.  Therefore the inheritance would be invalid.

Nope. I never said anything like that.

You were the one bringing up valid values.

> In a valid hierarchy, derived classes are always more specialized cases
> of their base classes.  In a case like this you can limit the wage in
> the derived class (Manager), but must stay within range of the base
> class (Employee).  A value in Manager that is not valid in Employee
> indicates an invalid inheritance.

True.

But totally irrelevant for my point, which has nothing to do
with valid values.

Arne

[toc] | [prev] | [next] | [standalone]


Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →

Back to top | Article view | comp.lang.java.programmer


csiph-web