deprecating abstract methods

Discussion in 'Java' started by Thomas Hawtin, Apr 10, 2006.

  1. Gabriel Belingueres wrote:
    >
    > How should I correctly declare deprecated an abstract method?


    With @deprecated and/or @Deprecated.

    > The thing is, that if I left the method abstract, I'm forced to
    > implement it, so the deprecation does not have any effect.


    It has effect for clients of the class.

    However, deprecation is not inherited. For instance, IIRC, for a long
    time Component.show was deprecated but Window.show was not.

    > But if I remove the abstract clause, I'm changing the method signature,


    The deprecated flag is not part of the signature.

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
     
    Thomas Hawtin, Apr 10, 2006
    #1
    1. Advertising

  2. Hi,

    My question is somewhat trivial and difficult at the same time.

    How should I correctly declare deprecated an abstract method?

    The thing is, that if I left the method abstract, I'm forced to
    implement it, so the deprecation does not have any effect.

    But if I remove the abstract clause, I'm changing the method signature,
    so I'm deprecating NOT the original method, but something else. Also,
    (maybe) different java compiler implementations will not recognize it
    as deprecated since I'm overriding the upper class method, so I'm
    technically not using the original deprecated method.

    Any comments will be welcomed.

    Regards,
    Gabriel
     
    Gabriel Belingueres, Apr 10, 2006
    #2
    1. Advertising

  3. > > The thing is, that if I left the method abstract, I'm forced to
    > > implement it, so the deprecation does not have any effect.

    >
    > It has effect for clients of the class.


    Surely. That's whom the @deprecated tag is meant to be.

    > However, deprecation is not inherited. For instance, IIRC, for a long
    > time Component.show was deprecated but Window.show was not.


    As for JDK 1.4.2, it is not deprecated. This is the root of the problem
    and
    here I point a difference between what I want to do and what is done in
    the
    AWT library.
    1) It seems to me that in AWT, they wanted that Window.show() not to be
    deprecated, or either they forgot to deprecate it because of the
    limitations
    of the deprecation mechanism.
    2) In class Component, the show() method is not abstract.

    > > But if I remove the abstract clause, I'm changing the method signature,

    >
    > The deprecated flag is not part of the signature.


    It's true, but the abstract keyword in the method signature is.

    I think that the actual problem here is that current compilers don't
    show a
    warning when a subclass override deprecated methods (either abstract or
    not)
    or implement them (when they are declared in an interface)

    I think it would be nice to have such a feature in the compiler...

    Gabriel
     
    Gabriel Belingueres, Apr 10, 2006
    #3
  4. Gabriel Belingueres wrote:
    >>> The thing is, that if I left the method abstract, I'm forced to
    >>> implement it, so the deprecation does not have any effect.

    >> It has effect for clients of the class.

    >
    > Surely. That's whom the @deprecated tag is meant to be.
    >
    >> However, deprecation is not inherited. For instance, IIRC, for a long
    >> time Component.show was deprecated but Window.show was not.

    >
    > As for JDK 1.4.2, it is not deprecated. This is the root of the problem
    > and
    > here I point a difference between what I want to do and what is done in
    > the
    > AWT library.
    > 1) It seems to me that in AWT, they wanted that Window.show() not to be
    > deprecated, or either they forgot to deprecate it because of the
    > limitations
    > of the deprecation mechanism.
    > 2) In class Component, the show() method is not abstract.


    In this particular case "they" seem to have been a bit schizophrenic
    about what to do about it.

    Bug 4090395, "show() is not flagged as deprecated", 03-NOV-1997, Closed,
    not a bug.
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4090395

    Bug 4689044, "Window.hide() and Window.show() should be deprecated",
    21-MAY-2002, Closed, fixed.
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4689044

    >>> But if I remove the abstract clause, I'm changing the method signature,

    >> The deprecated flag is not part of the signature.

    >
    > It's true, but the abstract keyword in the method signature is.


    Nor the abstract flag. (Code compiled referencing a class that uses a
    non-abstract method but run with an a version that is abstract, will
    dynamically link but throw an AbstractMethodError when the method is
    called.)

    Therefore, you can safely make an abstract method non-abstract.

    > I think that the actual problem here is that current compilers don't
    > show a
    > warning when a subclass override deprecated methods (either abstract or
    > not)
    > or implement them (when they are declared in an interface)
    >
    > I think it would be nice to have such a feature in the compiler...


    There are loads of bugs in the Bug Parade related to this. 1.6 currently
    does complain. Perhaps there should be a new annotation to state that a
    method may override/implement a deprecated method.
    @SuppressWarnings("deprecation") works in 1.6, but is heavy-handed as
    you don't want it applied to the method body (well, unless it has a
    super call).

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
     
    Thomas Hawtin, Apr 11, 2006
    #4
  5. Thomas Hawtin

    Chris Uppal Guest

    Gabriel Belingueres wrote:

    > How should I correctly declare deprecated an abstract method?
    >
    > The thing is, that if I left the method abstract, I'm forced to
    > implement it, so the deprecation does not have any effect.


    I would think about this slightly differently.

    A method declared abstract is a promise/requirement that concrete subclasses
    will provide it.

    If you deprecate it, then what you are doing is removing that /promise/ (or
    rather, warning people that the promise /will/ be removed later). You are not
    telling sub-class implementers that they mustn't implement a method with that
    signature, only that you no longer /require/ them to do so. Nothing whatever
    prevents, or should, prevent any subclass implementing such a method -- they
    can implement whatever methods they want -- but they should be aware that the
    method is no longer part of the semantics provided by the abstract class
    (considered as a framework).

    Take an example. Say we start with a class Animal:

    public abstract class Animal
    {
    public abstract void makeNoise();
    public void die()
    {
    this.makeNoise();
    this. lieStrangelyStill();
    this.decompose();
    }
    //...
    }

    And subclasses Cat and Dog:

    public class Cat
    extends Animal
    {
    public void makeNoise() { this.meaow(); }
    public void meaow() { /* ... */ }
    //...
    }
    public class Dog
    extends Animal
    {
    public void makeNoise() { this.woof(); }
    public void woof() { /* ... */ }
    //...
    }

    The makeNoise() method is used in two ways. One is that users of Animals can
    ask them to make a noise without knowing which /kind/ of animal they have. The
    other is the (hopefully documented) fact that Animals make a noise as they die.

    Now suppose we realise that animals don't all make noises, think Starfish for
    instance. So we decide to deprecate the makeNoise() method in Animal. That
    may have two different effects since makeNoise() may be used in two different
    ways.

    Let's take the effect on users of Animals first. Since that method is
    deprecated, they can no longer assume that any random Animal can makeNoise().
    But that in no way means that Dogs are suddenly silent! /If/ they know that
    they are dealing with a Dog then they can ask it to makeNoise(), just the same
    as they can ask it to woof(). Similarly they can ask a Cat to makeNoise() or
    meaow(). What has vanished is the connection between the two definitions of
    makeNoise() -- they have become independent of each other, and are now
    connected only by coincidence of name. But they are both still perfectly valid
    methods.

    So, in that case, you have removed the promise to users of Animals. As you
    say, there is a technical problem that subclasses are still (by Java rules)
    required to implement it, even though it is (logically) no longer necessary. A
    simple solution is to make it concrete (with an empty body) in the superclass;
    that will have no effect on subclasses that already implement that method, but
    will not constrain new subclasses.

    Now consider the effect on sub-class implementers. This is a completely
    different issue. The guarantee that die() will call makeNoise() has gone away.
    I don't think that's acceptable except in very tightly coupled (and necessarily
    small) code-bases. So you can't do that unless you are willing to change all
    the subclasses at the same time -- you have to find a different way to change
    the framework that won't break client code. (Arguably, part of the problem
    here is that die() called a /public/ method which subclasses were expected to
    implement -- a rather fragile design).

    So it depends on what you are doing with your abstract methods. In one case
    you can deprecate them without problems. In the other, you have to find some
    way to avoid deprecating it at all.

    -- chris
     
    Chris Uppal, Apr 11, 2006
    #5
  6. Hi,

    My situation is more like the second you write in your post.

    Thanks everyone for your answers.

    Since I've done a lot of modifications, I finally decided to change the
    framework version number (from 1.x to 2.x) and directly removed the
    conflicting methods, documenting all the changes I've done and writing
    a small migration document.

    So finally I choused to avoid the deprecation problem after all, but it
    was a useful discution anyway.

    Regards,
    Gabriel
     
    Gabriel Belingueres, Apr 17, 2006
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. DaKoadMunky
    Replies:
    4
    Views:
    552
    Lee Weiner
    Apr 20, 2004
  2. Iyer, Prasad C

    Abstract Methods & Abstract Class

    Iyer, Prasad C, Oct 20, 2005, in forum: Python
    Replies:
    0
    Views:
    534
    Iyer, Prasad C
    Oct 20, 2005
  3. Gerald Klix

    Re: Abstract Methods & Abstract Class

    Gerald Klix, Oct 20, 2005, in forum: Python
    Replies:
    1
    Views:
    345
    =?iso-8859-1?B?c+liYXN0aWVu?=
    Oct 20, 2005
  4. Gianni Mariani
    Replies:
    1
    Views:
    318
    Ian Collins
    Oct 28, 2008
  5. Xah Lee

    Apple is deprecating Java

    Xah Lee, Oct 21, 2010, in forum: Java
    Replies:
    80
    Views:
    1,699
    Arne Vajhøj
    Nov 18, 2010
Loading...

Share This Page