Solved Object oriented questions

Discussion in 'Plugin Development' started by Fl1pzta, Jul 5, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    Fl1pzta

    I've been programming for a while, but I'm still an amateur to most of you. I feel I have yet to have grasped the concept of object oriented programming and how to go about doing it. Maybe this topic will shed light on people who are interested as much as I am and feel they are in the same situation.

    I understand there are tutorials, but I feel a little one to one helps me learn best, so here's surely a basic example:

    If I wanted to create a new object like Bukkit created Player, but maybe for example I wanted players to have a list of keys then I'd create a new class(I think), say MyPlayer and it'd have some methods in it like listKeys() and addKey(String key). I'd think somewhere I'd have to create the player somewhere with MyPlayer example = new MyPlayer(); right?

    Then, I could add a key with example.addKey("blahblahblah"); , but how would I call listKeys for that specific player in another method. Some example code would be helpful, also don't I need a main method for when I'm creating the MyPlayer?

    Sorry if this sounds dumb to all of you, but we all have to start somewhere and I feel this is the best way for me. Thanks for understanding.
     
  2. Offline

    xTrollxDudex

    Fl1pzta
    It's good that you seek help from the community. You are not dumb. You are learning.
    First, to create something like that, you need to create a new class. This class contains fields that "define" an object.
    You can't directly access these fields. To do that, you use what coders call "getter and setters". These set and get the fields.
    To start with OOP, look for setter and getters on google!
     
  3. Offline

    Fl1pzta

  4. Offline

    chasechocolate

    Like xTrollxDudex look it up on Google, there's probably lots of video tutorials out there :) Anyways, here is an example:
    Code:java
    1. //Packages and imports
    2.  
    3. public class MyPlayer {
    4. private List<String> keys = new ArrayList<String>();
    5.  
    6. public MyPlayer(/* parameters, if any */){
    7. //Do something when a new instance of this class is called
    8. }
    9.  
    10. public List<String> getKeys(){
    11. return this.keys;
    12. }
    13.  
    14. public void addKey(String key){
    15. this.keys.add(key);
    16. }
    17.  
    18. //More getter and setter methods
    19. }
     
    xTrollxDudex likes this.
  5. Offline

    Compressions

    xTrollxDudex Well, you could use a static reference, but that's bad programming practice and can lead to issues, so it's best to stick with getters and setters.
     
    xTrollxDudex likes this.
  6. Offline

    xTrollxDudex

    chasechocolate
    Lots of videos? Lots of examples! :)

    EDIT:
    To use chasechocolate 's example,
    Code:java
    1. //create the object
    2. MyPlayer ply = new MyPlayer()
    3. //MyPlayer() would be the arguments if you had a constructor in the MyPlayer class
    4.  
    5. //do stuff with MyPlayer ply
    6. ply.getKeys();
    7. //this would give you the keys, if any from the instance ply
    8.  
    9. //add keys
    10. ply.addKey("hello!");
    11. //this would add a key to ply instance of MyPlayer. Since the addKey()(continued)
    12. //constructor has a string argument, the argument in ply.addKey() must be string
    13.  
    14. //NOW get the keys and send them out
    15. System.out.print(ply.getKeys());
    16. //Prints the keys from instance ply
     
    Fl1pzta likes this.
  7. Offline

    Fl1pzta

    Compressions You know, that's exactly why I'm asking this lol. I just get this feeling its wrong to do or else everyone else would be doing it.
    chasechocolate thanks a ton for the example. I understand I can then do
    Code:
    MyPlayer ex = new MyPlayer();
    ex.addKey("df");
    ex.getKeys();
    but what if I wanted to getKeys() for ex from a different class than when I added the key with addKey();.
    Hope that makes sense.
    I'd think it'd be similar to this:
    Code:
    Player player = new Player();
     
    player = Bukkit.getPlayer("name");
     
  8. Offline

    Compressions

    Fl1pzta You would create an instance of that class. I like to create all instances of classes in my main class.
    Code:
    OtherClass otherclass = new OtherClass();
    
    public static OtherClass getOtherClass() {
    return otherclass;
    }
    You can then call this elsewhere like so:
    Code:
    MainClass.getOtherClass().FUNCTION
     
  9. Offline

    xTrollxDudex

    Compressions Fl1pzta
    You can do
    Code:java
    1. //in class Main
    2. public static MyPlayer ply = new MyPlayer()
    3.  
    4. //in class other
    5. Main.ply.getKeys();
    6. //or
    7. Main.ply.addKey("blah");

    That MIGHT work. I've experimented with static HashMaps like that
     
  10. Offline

    Fl1pzta

    xTrollxDudex Compressions Maybe if I wanted all players to have a myPlayer then I could have a Hashmap of String & MyPlayer in my main class and access their MyPlayer based on their name. Wouldn't that work?
     
  11. Offline

    xTrollxDudex

    Fl1pzta
    Probably. Just create a listener and add the player to the HashMap on PlayerJoinEvent. Make sure to check if the HashMap contains their name first.
     
  12. Offline

    Compressions

  13. Offline

    ZeusAllMighty11

  14. Offline

    Fl1pzta

    Alright, I'm going to give it a try. Thank all of you guys so much for shedding some light on my issue. Really thankful. I'm working on a pretty big project if any of you are interested in being a companion.
    Thanks again: xTrollxDudex Compressions chasechocolate
     
    xTrollxDudex likes this.
  15. Offline

    xTrollxDudex

    TheGreenGamerHD likes this.
  16. Offline

    Compressions

    Fl1pzta I'd be happy to contribute some code if it's open-source on GitHub.
     
  17. Offline

    sayaad


    Yes, that would work but is also a horrible programming practice.
    If you want to become a great developer, you have to vision problems before they occur. Example:

    You wish to use a hashmap. What if an event that you use to add to a hashmap, and at the same time another event is called in which you read the hashmap? If you read and write to a hashmap at the same time, the server will ultimately freeze to a crash.

    On Topic:

    OOP is something everyone should practice, and it's extremely easy to accomplish, if you need any help, send a PM but for now I'll see what I can cover:

    Lets say you're presented with a task where you need to store a: Location, String(A player's name) and another String(A team name) for a minigame plugin. If you use the programming habits inherited by novice programmers, you'll end up doing alot of unnecessary calculations which ultimately eat the server's resources, lagging it.

    This can be easily achieved by creating an Object that house all of these variables.

    Code:java
    1. public class TeamWarp{
    2. private String warpName, teamName; //I'd prefer to use an enum for teams, but for simplicity in the understanding of OOP i'll use a string.
    3. private Location loc;
    4. public TeamWarp(String warpName, String teamName, Location location){
    5. this.warpName = warpName;
    6. this.teamName = teamName;
    7. loc = location;
    8. }
    9.  
    10. public String getWarpName(){
    11. return warpName;
    12. }
    13. public String getTeamName(){
    14. return teamName;
    15. }
    16. public Location getLocation(){
    17. return loc;
    18. }
    19. }


    That is a simple class that contains a constructor, and some getters, no methods even though it's able to house them. I made a post explaining these earlier.
    A constructor is simply a method you use to initialize the class, that is, give it a none-null value. In this case by setting the null variables inside of it to a value specified by the arguments: warpName, teamName and location.

    Creating a new instance of this class is simple, and is pretty much self explanatory providing you read what I said directly above. ^
    Code:java
    1. TeamWarp blueWarp = new TeamWarp(/*warpName*/ "Blue spawn", /*teamName*/ "Blue", /*location*/ player.getLocation());


    And getting the variables stored by the single object "blueWarp" is also very simple and I'm sure somewhat familiar to you.
    Code:java
    1. String warpName = blueWarp.getWarpName();
    2. String teamName = blueWarp.getTeamName();
    3. Location loc = blueWarp.getLocation();


    Well, there are better ways of handling a warp than that, but I created it as an example of how OOP is used, not as am efficient method for handling team warps in a minigame plugin. :p
     
  18. Offline

    Unknowncmbk

    Woah woah, how is a static reference a bad programming construct. Ever heard of a singleton? (If not look it up). It's not wise telling people about 'bad programming practice' if you don't know better yourself! :)

    The main use for get/set methods is to provide proper encapsulation of your object, not because it's a static variable, class, method etc.
     
  19. Offline

    Compressions

  20. Offline

    Unknowncmbk

    Yes, I know what static methods are, and they are great for access objects that need to be static, especially utility classes. Don't go linking programming constructs that you find on the web, this isn't real education.

    Edit: Btw you linked me a url that basically tells static methods are bad for implementation of an interface.
     
  21. Offline

    xTrollxDudex

    sayaad
    I realized that a long time ago. Anyway, you are a bit late, and basically your repeating chasechocolate and myself.
     
  22. Offline

    Fl1pzta

    sayaad but what if I wanted to get blueWarp from another method or even class than the one it was created in?

    Edit: Thanks for the example, btw. Oh, you're saying instead of creating a hashmap, put it all collectively. My mistake, but wouldn't that change depending on the situation?

    Edit2: Wait, I see what you're saying; a tree of different objects that are inside of a main object, which will eliminate multi-accessing issue that comes with something like a hashmap.

    sayaad

    Let's say in TeamWarp, you needed something like TeamWarpPlayer, because you needed to keep track of how many players and they had something that made them unique. Would I go about doing it this way?

    blueWarp.addPlayer(player);

    and in TeamWarp I'd have:
    Code:
    List<TeamWarpPlayer> teamPlayers;
    addPlayer(Player player){
    TeamWarpPlayer newPlayer = new TeamWarpPlayer(//whatever needs to be sent);
    teamPlayers.add(newPlayer);(I think thats the syntax for List :S)
    
    Hope that makes little sense, never done OOP.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 3, 2016
  23. Offline

    sayaad


    I'm not sure what you mean by, "Depending on the situation."

    In the case of where to get those Objects, you would store it like any other variable, in another Object. :p
    Example:

    Code:java
    1. public class Team{
    2. //other stuffs
    3. private List<TeamWarp> warps = new CopyOnWriteArrayList<TeamWarp>();
    4. //other stuffs you use in teams
    5.  
    6. public synchronized List<TeamWarp> getTeamWarps(){
    7. return warps;
    8. }
    9. public synchronized void addWarp(TeamWarp warp){
    10. getTeamWarps().add(warp);
    11. }
    12. public synchronized TeamWarp getWarp(String warpName){
    13. for(TeamWarp warp : getTeamWarps())
    14. if(warp.getName().equals(warpName))
    15. return warp;
    16. }
    17.  
    18. }


    Your plugin main class :

    Code:java
    1. public class MinigamePluginWithTeams extends JavaPlugin{
    2. private List<Team> teams = new CopyOnWriteArrayList<Team>();
    3.  
    4. public void onEnable(){/*Stuffs goes here*/}
    5. public void onEnable(){/*Stuffs goes here*/}
    6.  
    7. public synchronized List<Team> getTeams(){
    8. return teams;
    9. }
    10. public synchonized Team getTeam(someVariable){
    11. for(Team team : getTeams())
    12. if(team.someVariable.equals(someVariable))
    13. return team;
    14. }
    15. }


    So if you add you plugin to the constructor of other classes as "plugin", you do :

    TeamWarp warp = plugin.getTeam(someVariable).getWarp("Blue spawn");


    You should never store the Player interface in a list, otherwise you'll need to add methods to remove it when the player logs out etc to prevent memory leaks from overflowing logins/quits in a 24/7 server.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 3, 2016
  24. Offline

    Fl1pzta

    Well, yeah I'll add a method to remove it, but yeah I really am beginning to understand OOP more, I was always that guy to make everything static and throw it all in a hashmap and say it works, but I feel this is a more organized and well developed approach to the task at hand, but I definitely can see now where making an instance of something wouldn't be reasonable. So, thank you very much.

    This would be a great topic for people interested in OOP and who are getting started with Bukkit.
     
  25. Offline

    sayaad


    No problem! If you ever want some ways of making things more efficient, send me a PM. ;)

    Edit: I posted explaining getters and setters which play a major role in OOP. Take a look.
     
    xTrollxDudex likes this.
  26. Offline

    jayfella

    Every time i see "public static" on bukkit.org, I die a little inside. I feel like I am fighting people parsing html with regex. For the love of god, the static keyword is not for convenience, it has a specific use, and it certainly isn't to save you from having to use constructors correctly! Stop using "public static" everywhere!

    /rant.
     
    sayaad and Compressions like this.
Thread Status:
Not open for further replies.

Share This Page