OOP is both loved and hated as far as I can tell. Personally I find it very useful, but I dislike all kind of fanaticism. There are those that claim that you have to do this and that to "stay true to the OOP philosophy", that's where I leave the train. I use objects when I find it useful, and I use other constructs when I find that useful. I think Java "forces" a bit too much "OOP ideology" sometimes, but it mostly works out reasonably well.
Since the need for developers have become so great as the world have moved to using more and more software for everything, the "quality" of the "average developer" have fallen a lot in my experience (there simply aren't enough people with the right abilities available). This has lead to some strange trends like "functional programming" and languages that doesn't let the developer handle threads (and thus thread-safety). I just feel sad when I see this, but I guess it's just the way it has to be when the world wants to "dumb down" programming.
My impression is that there's quite a lot of people on the "functional programming" bandwagon these days, and they generally despise OOP. I strongly suspect that these people doesn't really grasp OOP, so they just find it frustrating. It's a bit funny really, because as I see it, "functional programming" is exactly what we had before OOP.
There's no reason to have to choose, my view is that you use whatever best fits the task at hand. Even though Java doesn't have "pure functions" (functions that doesn't belong to a class/object), there's already a well established tradition of making "utility classes" which are simply collections of static methods - aka "functions". Static methods in Java doesn't belong to any particular instance/object, and are thus in reality the same as a "old fashioned" function. They are useful when you want to process data instead of "creating control logic for an object".
What OOP comes down to is basically code reuse and logic separation. By using inheritance, you can make a "base class" (e.g a car) that has the fundamental properties that all cars share, and then you can make a subclass that inherits from the "base class" (e.g a blue sportscar). By doing this, you reuse the code that is common for all cars, while you only write the code specific for blue sportscars in the subclass. When this is done, it's much quicker when you want to make a red, electric city-car, since you already have the code for the fundamental things for a car, and you just have to make the specifics for that variant. If you didn't use OOP, you would have code for the blue sports car, and you would then have to copy/paste that code and modify it into a red city-car. You would then end up with two sets of code that were similar but not equal, and whenever you wanted to implement electric windows you'd have to do it for both types of cars. With OOP you can add electric windows to the "base car", and make it available to all the sub-types.
There are some terms in OOP which aren't intuitive (at least not to me) and that can confuse somewhat until you get familiar with them. Classes is one such thing, I still don't know how to accurately describe them, although I know very much what they are. Often, classes are physical (*.java) files, but not always. It is possible to declare classes within other classes, so some files will contain multiple classes. A class is... "the code that governs how a particular object type will behave". It's like the blueprint for the object, but the object/instance itself doesn't exist until it is created at runtime. Objects/instances are usually created using the "new" keyword, although there are other possibilities.
So, if you have a "base car" class and a "blue sportscar"subclass, you can create a new instance of a blue sportscar with "new BlueSportsCar()". You can create as many blue sportscars as you want when you have the class file(s) describing how to make one. Instances can also be destroyed, although not explicitly in Java. Java handles free'ing of objects for you, so all you have to do is to make sure that you no longer keep a reference to the instance, and Java will free it when it feels like it. This can take a while though, which is one of the reason why Java has a tendency to use more memory compared to languages where you have direct control of destruction. The plus-side is that you can't really create memory-leaks, and of course, you don't really have to think much about clean-up.
I don't really believe that you found the code you posted:
It doesn't make much sense to me at least. Instead, I guess it says:
That means something completely different ;P The reason is that convention dictates that classes starts with upper-case while variables/fields and metods starts with lower-case. What this code does is thus quite simple: It creates a new instance of class "Button" and assigns it to a new variable called "button". The first "Button" is the declaration for the new variable "button", and it dictates that it will be of type "Button". The part after "=" is the creation itself, which is done by calling the constructor for class "Button". In this case the constructor has no arguments, classes can have many constructors, and they often have a variety where you can choose the one that fits your use case best. When using a no-argument constructor, you will usually get a new instance with most things set to their defaults, when using constructors with more arguments, you can customize the new instance more to fit specific needs.
I've preached this many times before, but I claim that OOP is fundamentally quite easy to understand once you grasp the concepts. It can be complicated if it's used in a "complicated way", but fundamentally it's very straight forward. But, until you understand the fundamental concepts, nothing makes much sense at all.
I think it's helpful to think of the fact that when a class exists itself, it use no memory - it's only a blueprint. It's first when you create an instance, that memory for that object is reserved and populated by whatever information the class holds. For each new instance you create, new memory is reserved. The code in the class doesn't use memory, only the fields defined in the class ("class variables") that aren't static. If you have a field for "top speed" in your "car" class, memory will be reserved to hold the top speed value once for every car instance you create.
So, although public, protected and private certainly is a part of OOP, it's not where I would start when trying to understand it. These merely regulate the "access" to the class, field or method from other classes. Personally I almost feel like "private" should be banned, it sure is over-used in a lot of Java code. What it does is make inheritance impossible or at least very unpractical in many cases. It's such a waste IMO, so much code that needs to be duplicated just because some developer have decided to make some particular field or method private. Usually for no good reason in my view.