You have a very healthy attitude towards the topic, my friend, so let me offer my perspective. It would be interesting to see other experienced folks such as
Tramboi to chime in as well.
As a foreword, explaining all this is a bit tricky, because what I'm gonna tell you is based on 20+ years of coding experience (17 of which is coding 8 hours a day professionally). So many of the finer points wouldn't make too much sense until you actually experienced them in practice yourself. You know, like reading books about riding a bicycle vs actually riding it yourself. Many things look good on paper, sure, but the pain points become only obvious if you actually the use the tool day in, day out.
First, of all, if you're just starting out, you cannot go wrong with learning Java and the Java-brand of OOP first. You just gotta learn the main concepts of programming first and a wide variety of languages are fine for that. Depending on your goals, however, you might want to branch out/move on to other languages that might make development easier, more fun, quicker and so on. And there are so many factors to consider, for example:
- are you going to do this professionally? (because then there might be a language that you just have to use in a particular field or industry, whether you like or not, so you must learn that to get employed)
- are you just doing this for fun in your spare time? (then you can pick pretty much anything)
- what sort of program are you intending to write? (you'd pick different languages for server-side development, different languages for performance-critical tasks, etc.)
- how are you going to distribute your program? (if at all) (if you need to produce native executables, that restricts your choice of languages quite a bit)
- availability of tools, learning materials, libraries, etc.
OOP
Okay, so one of the problems with "mainstream OOP" is how it's implemented in Java and C++ and many other mainstream languages is actually a gimped version of the original vision of "object-orientedness". The original idea of building your program as objects that talk to each other via messages is coming from Smalltalk, which is an old dynamic language. But that's quite different to how OOP is realised in C++ and Java and the likes. C++ has evolved out of C, then Java out of C++, and their version of OOP is basically realised via method calls (objects in C++ are really just C structs, plus some dynamic dispatch VTABLE of function pointers for runtime polymorphism, and Java is quite similiar), whereas in Smalltalk-like languages it's more like objects having little "mailboxes" where they receive messages from other objects and then decide what to do with those messages. (As a side-note, OOP as realised in Objective-C is much closer to the "original true spirit" of using objects and is quite a joy to use. There's many other things to dislike about it, sure, and it's ultimate a hack on top of C, but their dynamic message passing OOP implementation is still quite nice).
A fun fact, the original inventor of OOP is quite horrified by how his idea of OOP was implemented in C++/Java etc., he has expressed this numerous times that this is definitely not what he had in mind. Gosling, one of the main inventors of Java has also said it many times in interviews when asked what would he do differently if he had a chance to re-design Java: "I would leave out the objects" (I'm paraphrasing).
Now, this doesn't mean, of course, that the Java/C++ brand of OOP is totally worthless and garbage; it has been proven to be actually quite useful to tackle certain types of problems. The prime examples are simulations and graphical user interfaces. Well, and because many (most?) games are about simulating a large number of various entities interacting with each other, OOP is kind of a good fit there. But OOP is not a *generally* useful paradigm for solving all sorts of programming problems, it's important to keep that in mind.
Once you've learned the basics of Java, I really recommend going through the
Effective Java book. It teaches you how to use the Java-styled OOP the best possible way, while also highlighting problems and common OOP pitfalls. It's really a goldmine of useful information and it's meant for the working programmer, it's 100% practical advice. Most of the concepts presented in the book are applicable to C++, C#, Python or any other language that uses the C++/Java style of OOP. It contains invaluable tips and best practices about mutability vs immutability, correct API design, serialisation, etc. that are generally applicable to programming in any language. It's a quite dense book and most of it just wouldn't make much sense for beginners, it's more aimed at intermediate level devs who have encountered the problems presented in the book in real-life already. But when you're ready, it will take you to the next level as a developer, trust me.
C++
C++ is a strange animal... First of all, unless you really must use C++ for some reason (e.g. developing for consoles where you just have to interact with SDKs written in C/C++), it's almost invariably the wrong choice for new projects nowadays. The language just contains too much cruft accumulated over decades, it's overly complex and tedious to use, especially as a beginner. You can spend many years just learning the intricacies of C++, which of it's many features are actually useful, etc etc.
The reason why it's still used is because it's quite ubiquitous, you can compile C++ for every imaginable hardware to produce standalone executables and it's low-level enough so there's usually a way to utilise any low-level feature that the OS and the CPU provides (e.g. using SIMD vector instructions which you cannot easily use (or at all) in Java, C#, JavaScript and other high-level languages). You can do your own memory management in C++ (well, you must), which can be a huge advantage or a huge disadvantage, depending on your needs. In most high level languages you cannot really influence how memory is allocated/freed or in what pattern; it turns out with modern CPU this can have serious performance implications. So people writing high-performance 3D engines, ray-tracers, video encoders, scientific software that need to utilise the CPU/memory system to the maximum often just bite the bullet and use C++ because they simply just need the low-level access. But as I said, the language is tedious to use compared to other high-level languages readily available nowadays, so what most people resort to is to write just a small performance critical core in C++ and the rest in some much more productive and pleasant to use high level language. A very typical combo for game development is C++ for the 3D engine and Lua for everything else. For non-AAA 3D games or 2D games you don't even need C++, you can most likely get away with just using Lua or some other high-level language.
In short, in 2020, if you're just starting out, learning C++ is a not a good investment of your time, unless you're absolutely sure you will need it (e.g. you want to become an engine-developer in the gaming industry). If I were you, I'd just learn some basic/intermediate C as it's always useful to know how things work under the hood with pointers, how is the memory laid out, etc. A good way to think about C is as a cross-platform high-level assembly language. It is kind of timeless and it might come in handy for you because practically all high level languages can interface with native C code, so you could write most of your program in a high-level language and only convert some performance-critical sections to C later, if needed.
To sum up, C++ won't really teach you any high-level programming concepts that other, better high-level languages wouldn't in a much more enjoyable fashion (e.g. no need for manual memory management, no weird crashes when you did something wrong, etc.)
Scheme/LISP
This point might be controversial to some, but I personally strongly believe that if you want to become a really good programmer, you'll need to become at least a bit familiar with Scheme or LISP at some point in your career. Why is that so? Well, most programmers are familiar with the "traditional" ways of writing programs, so you write your source code, compile your program, then test it, then make modifications and repeat the whole cycle. What if I told you that you could modify a program while it's running, experiment with it without having to recompile, replace functions, change variables, basically all that you can imagine (and more!)? It's actually way more flexible than the stuff you can do with a regular debugger, it's really an interactive process that has to be experienced, it's magical.
The truth is, you might never actually get to use Scheme or LISP commercially or even in hobby projects, but just getting familiar with the language sort of rewires your brain permanently (for the better!), it gives you new insights into writing computer programs and you will be able to carry this knowledge over to any language you happen to use in your work.
One of the best ways to get acquainted with Scheme/LISP is in my opinion it the classic "Structure and Interpretation of Computer Programs" MIT university textbook. The full text is available online for free, plus you can watch the original lecture videos from 1986, they're very motivational and contain a wealth of good advice. Also, try to solve all the exercises from the book, if you're just reading it you'd get maybe just 10% of its potential value.
https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html
https://www.youtube.com/watch?v=-J_xL4IGhJA&list=PLE18841CABEA24090
Conclusion
My recommendation to become a well-rounded programmer:
- continue learning Java, read the Effective Java book when you're ready (you could substitute Java with C#, but you can always pick up the other later, they're not that different)
- learn at least on dynamic scripting language (Lua is nice, but so is Python)
- learn C to understand how the machine is really working (beginner/intermediate level is enough, unless you really need to do low-level stuff routinely)
- get at least a bit familiar with Scheme/LISP to broaden your horizons (!!!)
- optionally, if you want to do web development, JavaScript is a must (the language is improving and it has some good parts, but it lets you pick up bad habits if you learn it as your first language, so I'd avoid it unless you really need it)
With this foundation you can become productive in pretty much any other mainstream language easily when needed.
And this is long enough already, if you have further questions, just ask!