How to cast a different subclass to a superclass in a loop?












-1















I am writing a markup parser in Java. I have created classes for each kind of token based on a superclass (generic?) I'm calling BaseToken. Inside each token is a Pattern object and a String for the content. I am writing a function that finds the nearest token in a string from a certain start point in the string. In order to find out what pattern will work best, I have created an array of BaseToken instances that will be looped over when testing.



BaseToken is defined as:



public class BaseToken{
public Pattern pattern = null;
private BaseToken children;
}


An example of a subclass of BaseToken looks like this:



public class H3 extends BaseToken{
public Pattern pattern = Pattern.compile("\=\=\=([^\s*].*?)\=\=\=");
}


My problem with this is that in order to access the Pattern specific to the subclass, I need to specifically cast that subclass to its instance inside the array. Since the token types will be different each loop, I can't just cast it with (subclass)instance.



I've tried to search for similar situations to mine but I don't actually know what to search for. If this is a duplicate of an existing problem, I'm sorry.










share|improve this question


















  • 1





    If there is a field pattern in BaseToken, you don't need to declare an identical field in the subclass. Just assign it to something.

    – khelwood
    Nov 21 '18 at 19:20








  • 2





    Use methods, not public fields. That's what makes polymorphism possible.

    – JB Nizet
    Nov 21 '18 at 19:20











  • You can use reflection but it will get complicated. For your problem I would suggest you to make 'BaseToken' as abstract class and create a abstract method 'abstract Pattern getPattern' and let every child implement that.

    – Suryavel TR
    Nov 21 '18 at 19:23
















-1















I am writing a markup parser in Java. I have created classes for each kind of token based on a superclass (generic?) I'm calling BaseToken. Inside each token is a Pattern object and a String for the content. I am writing a function that finds the nearest token in a string from a certain start point in the string. In order to find out what pattern will work best, I have created an array of BaseToken instances that will be looped over when testing.



BaseToken is defined as:



public class BaseToken{
public Pattern pattern = null;
private BaseToken children;
}


An example of a subclass of BaseToken looks like this:



public class H3 extends BaseToken{
public Pattern pattern = Pattern.compile("\=\=\=([^\s*].*?)\=\=\=");
}


My problem with this is that in order to access the Pattern specific to the subclass, I need to specifically cast that subclass to its instance inside the array. Since the token types will be different each loop, I can't just cast it with (subclass)instance.



I've tried to search for similar situations to mine but I don't actually know what to search for. If this is a duplicate of an existing problem, I'm sorry.










share|improve this question


















  • 1





    If there is a field pattern in BaseToken, you don't need to declare an identical field in the subclass. Just assign it to something.

    – khelwood
    Nov 21 '18 at 19:20








  • 2





    Use methods, not public fields. That's what makes polymorphism possible.

    – JB Nizet
    Nov 21 '18 at 19:20











  • You can use reflection but it will get complicated. For your problem I would suggest you to make 'BaseToken' as abstract class and create a abstract method 'abstract Pattern getPattern' and let every child implement that.

    – Suryavel TR
    Nov 21 '18 at 19:23














-1












-1








-1








I am writing a markup parser in Java. I have created classes for each kind of token based on a superclass (generic?) I'm calling BaseToken. Inside each token is a Pattern object and a String for the content. I am writing a function that finds the nearest token in a string from a certain start point in the string. In order to find out what pattern will work best, I have created an array of BaseToken instances that will be looped over when testing.



BaseToken is defined as:



public class BaseToken{
public Pattern pattern = null;
private BaseToken children;
}


An example of a subclass of BaseToken looks like this:



public class H3 extends BaseToken{
public Pattern pattern = Pattern.compile("\=\=\=([^\s*].*?)\=\=\=");
}


My problem with this is that in order to access the Pattern specific to the subclass, I need to specifically cast that subclass to its instance inside the array. Since the token types will be different each loop, I can't just cast it with (subclass)instance.



I've tried to search for similar situations to mine but I don't actually know what to search for. If this is a duplicate of an existing problem, I'm sorry.










share|improve this question














I am writing a markup parser in Java. I have created classes for each kind of token based on a superclass (generic?) I'm calling BaseToken. Inside each token is a Pattern object and a String for the content. I am writing a function that finds the nearest token in a string from a certain start point in the string. In order to find out what pattern will work best, I have created an array of BaseToken instances that will be looped over when testing.



BaseToken is defined as:



public class BaseToken{
public Pattern pattern = null;
private BaseToken children;
}


An example of a subclass of BaseToken looks like this:



public class H3 extends BaseToken{
public Pattern pattern = Pattern.compile("\=\=\=([^\s*].*?)\=\=\=");
}


My problem with this is that in order to access the Pattern specific to the subclass, I need to specifically cast that subclass to its instance inside the array. Since the token types will be different each loop, I can't just cast it with (subclass)instance.



I've tried to search for similar situations to mine but I don't actually know what to search for. If this is a duplicate of an existing problem, I'm sorry.







java subclass superclass






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 '18 at 19:16









Nat OsakaNat Osaka

32




32








  • 1





    If there is a field pattern in BaseToken, you don't need to declare an identical field in the subclass. Just assign it to something.

    – khelwood
    Nov 21 '18 at 19:20








  • 2





    Use methods, not public fields. That's what makes polymorphism possible.

    – JB Nizet
    Nov 21 '18 at 19:20











  • You can use reflection but it will get complicated. For your problem I would suggest you to make 'BaseToken' as abstract class and create a abstract method 'abstract Pattern getPattern' and let every child implement that.

    – Suryavel TR
    Nov 21 '18 at 19:23














  • 1





    If there is a field pattern in BaseToken, you don't need to declare an identical field in the subclass. Just assign it to something.

    – khelwood
    Nov 21 '18 at 19:20








  • 2





    Use methods, not public fields. That's what makes polymorphism possible.

    – JB Nizet
    Nov 21 '18 at 19:20











  • You can use reflection but it will get complicated. For your problem I would suggest you to make 'BaseToken' as abstract class and create a abstract method 'abstract Pattern getPattern' and let every child implement that.

    – Suryavel TR
    Nov 21 '18 at 19:23








1




1





If there is a field pattern in BaseToken, you don't need to declare an identical field in the subclass. Just assign it to something.

– khelwood
Nov 21 '18 at 19:20







If there is a field pattern in BaseToken, you don't need to declare an identical field in the subclass. Just assign it to something.

– khelwood
Nov 21 '18 at 19:20






2




2





Use methods, not public fields. That's what makes polymorphism possible.

– JB Nizet
Nov 21 '18 at 19:20





Use methods, not public fields. That's what makes polymorphism possible.

– JB Nizet
Nov 21 '18 at 19:20













You can use reflection but it will get complicated. For your problem I would suggest you to make 'BaseToken' as abstract class and create a abstract method 'abstract Pattern getPattern' and let every child implement that.

– Suryavel TR
Nov 21 '18 at 19:23





You can use reflection but it will get complicated. For your problem I would suggest you to make 'BaseToken' as abstract class and create a abstract method 'abstract Pattern getPattern' and let every child implement that.

– Suryavel TR
Nov 21 '18 at 19:23












2 Answers
2






active

oldest

votes


















2














This is not the best way to make use of polymorphism. You should either turn BaseToken into an interface or into an abstract class, and create a method specific to manipulating the pattern. You should then have the subtypes implement that method, so that each class can manipulate its own pattern (which should be private to the class) in its own way without breaking the calling code (you should read on Liskov's substitution principle).



A simple example:



abstract class BaseToken {
abstract Pattern getPattern();
}

class H3 extends BaseToken {
private Pattern pattern = ...

Pattern getPattern() {
return pattern;
}
}

class Whatever extends BaseToken {
private Pattern aCompletelyDifferentPattern = ...

Pattern getPattern() {
return aCompletelyDifferentPattern;
}
}


With this, you can now do something like:



BaseToken token = new H3();
Pattern currentPattern = token.getPattern();


No matter what subclass you use, this will always return the corresponding pattern.






share|improve this answer

































    1














    I suggest you make BaseToken into an abstract class:



    public abstract class BaseToken {
    public abstract Pattern getPattern();

    /* ...other stuff */
    }


    Then, your various tokens can extend it and return their specific patterns:



    public class H3 extends BaseToken {
    public Pattern getPattern() {
    return Pattern.compile("\=\=\=([^\s*].*?)\=\=\=");
    }
    }


    Having a BaseToken bt (and not knowing its exact subtype) you can still call bt.getPattern().






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      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: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      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%2fstackoverflow.com%2fquestions%2f53419101%2fhow-to-cast-a-different-subclass-to-a-superclass-in-a-loop%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      2














      This is not the best way to make use of polymorphism. You should either turn BaseToken into an interface or into an abstract class, and create a method specific to manipulating the pattern. You should then have the subtypes implement that method, so that each class can manipulate its own pattern (which should be private to the class) in its own way without breaking the calling code (you should read on Liskov's substitution principle).



      A simple example:



      abstract class BaseToken {
      abstract Pattern getPattern();
      }

      class H3 extends BaseToken {
      private Pattern pattern = ...

      Pattern getPattern() {
      return pattern;
      }
      }

      class Whatever extends BaseToken {
      private Pattern aCompletelyDifferentPattern = ...

      Pattern getPattern() {
      return aCompletelyDifferentPattern;
      }
      }


      With this, you can now do something like:



      BaseToken token = new H3();
      Pattern currentPattern = token.getPattern();


      No matter what subclass you use, this will always return the corresponding pattern.






      share|improve this answer






























        2














        This is not the best way to make use of polymorphism. You should either turn BaseToken into an interface or into an abstract class, and create a method specific to manipulating the pattern. You should then have the subtypes implement that method, so that each class can manipulate its own pattern (which should be private to the class) in its own way without breaking the calling code (you should read on Liskov's substitution principle).



        A simple example:



        abstract class BaseToken {
        abstract Pattern getPattern();
        }

        class H3 extends BaseToken {
        private Pattern pattern = ...

        Pattern getPattern() {
        return pattern;
        }
        }

        class Whatever extends BaseToken {
        private Pattern aCompletelyDifferentPattern = ...

        Pattern getPattern() {
        return aCompletelyDifferentPattern;
        }
        }


        With this, you can now do something like:



        BaseToken token = new H3();
        Pattern currentPattern = token.getPattern();


        No matter what subclass you use, this will always return the corresponding pattern.






        share|improve this answer




























          2












          2








          2







          This is not the best way to make use of polymorphism. You should either turn BaseToken into an interface or into an abstract class, and create a method specific to manipulating the pattern. You should then have the subtypes implement that method, so that each class can manipulate its own pattern (which should be private to the class) in its own way without breaking the calling code (you should read on Liskov's substitution principle).



          A simple example:



          abstract class BaseToken {
          abstract Pattern getPattern();
          }

          class H3 extends BaseToken {
          private Pattern pattern = ...

          Pattern getPattern() {
          return pattern;
          }
          }

          class Whatever extends BaseToken {
          private Pattern aCompletelyDifferentPattern = ...

          Pattern getPattern() {
          return aCompletelyDifferentPattern;
          }
          }


          With this, you can now do something like:



          BaseToken token = new H3();
          Pattern currentPattern = token.getPattern();


          No matter what subclass you use, this will always return the corresponding pattern.






          share|improve this answer















          This is not the best way to make use of polymorphism. You should either turn BaseToken into an interface or into an abstract class, and create a method specific to manipulating the pattern. You should then have the subtypes implement that method, so that each class can manipulate its own pattern (which should be private to the class) in its own way without breaking the calling code (you should read on Liskov's substitution principle).



          A simple example:



          abstract class BaseToken {
          abstract Pattern getPattern();
          }

          class H3 extends BaseToken {
          private Pattern pattern = ...

          Pattern getPattern() {
          return pattern;
          }
          }

          class Whatever extends BaseToken {
          private Pattern aCompletelyDifferentPattern = ...

          Pattern getPattern() {
          return aCompletelyDifferentPattern;
          }
          }


          With this, you can now do something like:



          BaseToken token = new H3();
          Pattern currentPattern = token.getPattern();


          No matter what subclass you use, this will always return the corresponding pattern.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 21 '18 at 19:29

























          answered Nov 21 '18 at 19:24









          Ricardo CosteiraRicardo Costeira

          6241614




          6241614

























              1














              I suggest you make BaseToken into an abstract class:



              public abstract class BaseToken {
              public abstract Pattern getPattern();

              /* ...other stuff */
              }


              Then, your various tokens can extend it and return their specific patterns:



              public class H3 extends BaseToken {
              public Pattern getPattern() {
              return Pattern.compile("\=\=\=([^\s*].*?)\=\=\=");
              }
              }


              Having a BaseToken bt (and not knowing its exact subtype) you can still call bt.getPattern().






              share|improve this answer




























                1














                I suggest you make BaseToken into an abstract class:



                public abstract class BaseToken {
                public abstract Pattern getPattern();

                /* ...other stuff */
                }


                Then, your various tokens can extend it and return their specific patterns:



                public class H3 extends BaseToken {
                public Pattern getPattern() {
                return Pattern.compile("\=\=\=([^\s*].*?)\=\=\=");
                }
                }


                Having a BaseToken bt (and not knowing its exact subtype) you can still call bt.getPattern().






                share|improve this answer


























                  1












                  1








                  1







                  I suggest you make BaseToken into an abstract class:



                  public abstract class BaseToken {
                  public abstract Pattern getPattern();

                  /* ...other stuff */
                  }


                  Then, your various tokens can extend it and return their specific patterns:



                  public class H3 extends BaseToken {
                  public Pattern getPattern() {
                  return Pattern.compile("\=\=\=([^\s*].*?)\=\=\=");
                  }
                  }


                  Having a BaseToken bt (and not knowing its exact subtype) you can still call bt.getPattern().






                  share|improve this answer













                  I suggest you make BaseToken into an abstract class:



                  public abstract class BaseToken {
                  public abstract Pattern getPattern();

                  /* ...other stuff */
                  }


                  Then, your various tokens can extend it and return their specific patterns:



                  public class H3 extends BaseToken {
                  public Pattern getPattern() {
                  return Pattern.compile("\=\=\=([^\s*].*?)\=\=\=");
                  }
                  }


                  Having a BaseToken bt (and not knowing its exact subtype) you can still call bt.getPattern().







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 21 '18 at 19:26









                  Pedro LMPedro LM

                  694310




                  694310






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • 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%2fstackoverflow.com%2fquestions%2f53419101%2fhow-to-cast-a-different-subclass-to-a-superclass-in-a-loop%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

                      Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                      ComboBox Display Member on multiple fields

                      Is it possible to collect Nectar points via Trainline?