I just started learning java yesterday since i want to make android apps. So far i only know c. I am reading a book called "Head first java" and it keeps talking about object and classes which are pretty new to me. I just have one question and if someone can clarify this for me that'd be very helpful:
What is/are the difference(s) between classes(java) and structures(c)?
ps: I'd also love if you can recommend me a book that really is for absolute beginners because the book i'm reading right now doesn't have enough details for those that are completely new to object oriented programming. Thank you.
No. You don't get inheritance, methods, abstract methods, polymorphism, and many more object oriented concepts with Structs.
You can try to make C conform to object oriented behavior using structs, but that's different from using an object oriented language.
"Aren't classes in Java equivalent to structures in c?"
Short answer, No.
My answer is too short cause the differences is the difference between two completely different paradigms, and it needs a complete book (not even a chapter) like : "Thinking in java".
Java classes perform several roles, only one of which is (implicitly) defining the layout of the data structure called the instance of that class, but you are right in thinking that objects are essentially data structures, just like instances of struct.
The main difference is that C's struct is something much more raw and "close to the metal" than a Java class. Basically, with much additional framework code and strict adherence to many conventions you could reimplement a good part of Java's objects, but the syntax would not be as clean as in Java.
There are many other differences, such as what exactly is covered by compiler's static checking, automatic memory management, etc. In the end, differences outweigh similarities, but as a point of understanding, it is not wrong to compare Java objects with C structs.
I know, that I am contradicting the view of a lot of people here, but you are right, a class really is nothing more or less than a struct with a lot of bells and whistles.
To be precise, the C++ language actually specifies that an instance of a class without virtual functions and/or virtual inheritance has the same memory layout as a C struct with the same data members in the same order.
All that is added to the struct to provide runtime polymorphism is a single v-table pointer, which is used to look up the virtual members. Inheritance is generated by including the base class structures as data members of the child class struct.
Of course, when you think about it for a second, you realize that classes must be implemented with structs, one way or another. C++/Java classes must be implemented somehow, after all. And it helps to remind yourself that object orientation is not primarily a language feature, it is a paradigm that can be used in any imperative programming language. It can be used in Java, in C++, in C, in Pascal, in Fortran, and even in assembler. All which the so-called object oriented languages add, is syntactic sugar to handle all the technical stuff of object orientation.
Nevertheless, it is important to learn all the bells and whistles when you start working in C++ or Java.
Related
I recently learned C. I am Confused after reading about OOPS.
The article about OOPS said the Code can be reused in Java by Inheritance concept unlike C which is Procedural Programming Paradigm. But the same can be done in C by having some Header file with all the functions that we want to reuse and Include the Head file.
My Question is what actually the "Reuse" word mean in OOPS world?
It's nonsense -- ignore it. There is nothing inherent about C or Java that makes code written in those languages any more or less "reusable" between projects.
The author may be making the assumption that all Java code can be made "reusable" by extending it with subclasses, and that C code cannot be "reused" because the language does not support subclasses. However, they are wrong, because:
This approach to "reuse" assumes that code can only ever be reused by extending, not by modifying it. This is, of course, not true.
Not all Java code can be usefully extended with subclasses. In fact, most Java code cannot be reused this way; it must be specifically architected to support this usage. (For example, a final class cannot be extended. Nor is it possible to extend a class consisting of a single large function without reimplementing the entire function -- at which point, nothing is actually being "reused".)
I know that Java is mostly object oriented language since you can do things like encapsulation, inheritance, and run-time polymorphism.
But when I watch a lot of talks on youtube about RxJava they say under Android you work with imperative rules? Does this relate to the life-cycle methods?
When I work with POJO's isn't that Object Oriented? Does this have to with how we handle data through our architecture layers? I'm getting confused with all these 'paradigms' and 'styles' especially since RxAndroid is getting thrown into the mix with 'functional-reactive' style.
First of all: Android is an operating system, not a programming language. That language is mainly object oriented, but lately a lot of effort is going into making java more suitable for functional programming. Frameworks such as RxJava emphasize that, too.
Of course, there are different programming models that can be used on the Android platform.
Coming from there: there is simply no sense in assuming that this large, complex environment can be reduced to some simple, always correct single word description. It is a combination of many different aspects.
Or as the US citizens say: in pluribus unum.
Android itself is a platform, not a language, so the question contains a category mistake.
In general, the only way this kind of question can be definitively answered is by resort to fundamental definitions. These were stated by Peter Wegner in 1987 in the paper 'Dimensions of Object-based Language Design'.
Wegner provides the following definitions:
Object-based: a language is object-based if it supports objects as a language feature.
Class-based: an object-based language is class-based (classical) if every object has a class.
Object-oriented: an object-based language is object-oriented if its objects belong to classes and class hierarchies can be incrementally designed by an inheritance mechanism.
I think you've got it a little bit wrong.
Java is an imperative language. You'd be better to ask what the difference between declarative vs imperative programming, or the difference between object oriented and functional programming.
Here is a great article on imperative vs declarative:
https://tylermcginnis.com/imperative-vs-declarative-programming/
Here is a stack overflow answer explaining the difference between object oriented and functional:
Functional programming vs Object Oriented programming
Android provides a framework written in java. Android isn't a language, but Java is. Java is an object oriented language.
I hope that clears things up a bit.
Some people say that Java is more like a hybrid, taking this piece from this article:
That said, Java is not a pure Object-Oriented language. Someone said Java is a hybrid, which, IMO, is an accurate description. I would posit Java is a dirty hybrid of an OO language. Consider:
String s = string2.trim();
First, since "String" is immutable, the above code reeks of functional programming. The "trim()" operation should cause the whitespace to be trimmed off both ends of "string2", without needing reassignment. That is to say, operations should act on the data as close to the object as possible. This, to me, makes Java feel dirty (it also leads to tightly-coupled systems due to the prevalence of "get" accessor methods, but that's another topic entirely). Ahem, what? That example is perfectly OO. Object-orientation does not make mutable state necessary. Actually, since strings are passed around so often, the lack of mutator methods really just saves a lot of headache.
Second, Java cannot alter the behaviour of all messages. It mixes the types of "operations" available to objects, depending on their type. The "+" is equally applicable to ints as it is Strings, but not to Matrices, or Colors. This isn't so bad, because you can do matrix.add( matrix ), but serves to illustrate the point about Java being 'dirty' (or 'impure', if you prefer).
Lastly, it is a hybrid to provide performance gains. Even though Smalltalk has an advanced virtual machine, its inability (when I was using it) to provide a machine-correlated bytecode for integer math placed a significant performance impact on its entire environment. Being a hybrid, Java cannot be called a true Object-Oriented language. But then, why does it matter?Use the right tool for the job and life will be happy!*
So:
You can work all like procedural programming if you want, and not use anything of OOP, but also, is not pure OOP programming, because not everything in Java is an object.
Also:
Java8 introduces some concepts about Functional programming, one of them is the use of lambdas.
In resume, Java is imperative, OOP and functional language(dep on version).
What does it mean to say "with inheritance you're locked into compile-time decisions about code behavior".
I suggest this post from Donal Fellows on Programmers,
Some languages are pretty strongly static, and only allow the
specification of the inheritance relationship between two classes at
the time of definition of those classes. For C++, definition time is
practically the same as compilation time. (It's slightly different in
Java and C#, but not very much.) Other languages allow much more
dynamic reconfiguration of the relationship of classes (and class-like
objects in Javascript) to each other; some go as far as allowing the
class of an existing object to be modified, or the superclass of a
class to be changed. (This can cause total logical chaos, but can also
model real world nasties quite well.)
But it is important to contrast this to composition, where the
relationship between one object and another is not defined by their
class relationship (i.e., their type) but rather by the references
that each has in relation to the other. General composition is a very
powerful and ubiquitous method of arranging objects: when one object
needs to know something about another, it has a reference to that
other object and invokes methods upon it as necessary. As soon as you
start looking for this super-fundamental pattern, you'll find it
absolutely everywhere; the only way to avoid it is to put everything
in one object, which would be massively dumb! (There's also stricter
UML composition/aggregation, but that's not what the GoF book is
talking about there.)
One of the things about the composition relationship is that
particular objects do not need to be hard-bound to each other. The
pattern of concrete objects is very flexible, even in very static
languages like C++. (There is an upside to having things very static:
it is possible to analyse the code more closely and — at least
potentially — issue better code with less overhead.) To recap,
Javascript, as with many other dynamic languages, can pretend it
doesn't use compilation at all; just pretence, of course, but the
fundamental language model doesn't require transformation to a fixed
intermediate format (e.g., a “binary executable on disk”). That
compilation which is done is done at runtime, and can be easily redone
if things vary too much. (The fascinating thing is that such a good
job of compilation can be done, even starting from a very dynamic
basis…)
Some GoF patterns only really make sense in the context of a language
where things are fairly static. That's OK; it just means that not all
forces affecting the pattern are necessarily listed. One of the key
points about studying patterns is that it helps us be aware of these
important differences and caveats. (Other patterns are more universal.
Keep your eyes open for those.)
I am a long time OO programmer and a functional programming newbie. From my little exposure algebraic data types only look like a special case of inheritance to me where you only have one level hierarchy and the super class cannot be extended outside the module.
So my (potentially dumb) question is: If ADTs are just that, a special case of inheritance (again this assumption may be wrong; please correct me in that case), then why does inheritance gets all the criticism and ADTs get all the praise?
Thank you.
I think that ADTs are complementary to inheritance. Both of them allow you to create extensible code, but the way the extensibility works is different:
ADTs make it easy to add new functionality for working with existing types
You can easily add new function that works with ADT, which has a fixed set of cases
On the other hand, adding new case requires modifying all functions
Inheritance makes it easy to add new types when you have fixed functionality
You can easily create inherited class and implement fixed set of virtual functions
On the other hand, adding a new virtual function requires modifying all inherited classes
Both object-oriented world and functional world developed their ways to allow the other type of extensibility. In Haskell, you can use typeclasses, in ML/OCaml, people would use dictionary of functions or maybe (?) functors to get the inhertiance-style extensibility. On the other hand, in OOP, people use the Visitor pattern, which is essentially a way to get something like ADTs.
The usual programming patterns are different in OOP and FP, so when you're programming in a functional language, you're writing the code in a way that requires the functional-style extensibility more often (and similarly in OOP). In practice, I think it is great to have a language that allows you to use both of the styles depending on the problem you're trying to solve.
Tomas Petricek has got the fundamentals exactly right; you might also want to look at Phil Wadler's writing on the "expression problem".
There are two other reasons some of us prefer algebraic data types over inheritance:
Using algebraic data types, the compiler can (and does) tell you if you have forgotten a case or if a case is redundant. This ability is especially useful when there are many more operations on things than there are kinds of thing. (E.g., many more functions than algebraic datatypes, or many more methods than OO constructors.) In an object-oriented language, if you leave a method out of a subclass, the compiler can't tell whether that's a mistake or whether you intended to inherit the superclass method unchanged.
This one is more subjective: many people have noted that if inheritance is used properly and aggressively, the implementation of an algorithm can easily be smeared out over a half a dozen classes, and even with a nice class browser at can be hard to follow the logic of the program (data flow and control flow). Without a nice class browser, you have no chance. If you want to see a good example, try implementing bignums in Smalltalk, with automatic failover to bignums on overflow. It's a great abstraction, but the language makes the implementation difficult to follow. Using functions on algebraic data types, the logic of your algorithm is usually all in one place, or if it is split up, its split up into functions which have contracts that are easy to understand.
P.S. What are you reading? I don't know of any responsible person who says "ADTs good; OO bad."
In my experience, what people usually consider "bad" about inheritance as implemented by most OO languages is not the idea of inheritance itself but the idea of subclasses modifying the behavior of methods defined in the superclass (method overriding), specifically in the presence of mutable state. It's really the last part that's the kicker. Most OO languages treat objects as "encapsulating state," which amounts to allowing rampant mutation of state inside of objects. So problems arise when, for example, a superclass expects a certain method to modify a private variable, but a subclass overrides the method to do something completely different. This can introduce subtle bugs which the compiler is powerless to prevent.
Note that in Haskell's implementation of subclass polymorphism, mutable state is disallowed, so you don't have such issues.
Also, see this objection to the concept of subtyping.
I am a long time OO programmer and a functional programming newbie. From my little exposure algebraic data types only look like a special case of inheritance to me where you only have one level hierarchy and the super class cannot be extended outside the module.
You are describing closed sum types, the most common form of algebraic data types, as seen in F# and Haskell. Basically, everyone agrees that they are a useful feature to have in the type system, primarily because pattern matching makes it easy to dissect them by shape as well as by content and also because they permit exhaustiveness and redundancy checking.
However, there are other forms of algebraic datatypes. An important limitation of the conventional form is that they are closed, meaning that a previously-defined closed sum type cannot be extended with new type constructors (part of a more general problem known as "the expression problem"). OCaml's polymorphic variants allow both open and closed sum types and, in particular, the inference of sum types. In contrast, Haskell and F# cannot infer sum types. Polymorphic variants solve the expression problem and they are extremely useful. In fact, some languages are built entirely on extensible algebraic data types rather than closed sum types.
In the extreme, you also have languages like Mathematica where "everything is an expression". Thus the only type in the type system forms a trivial "singleton" algebra. This is "extensible" in the sense that it is infinite and, again, it culminates in a completely different style of programming.
So my (potentially dumb) question is: If ADTs are just that, a special case of inheritance (again this assumption may be wrong; please correct me in that case), then why does inheritance gets all the criticism and ADTs get all the praise?
I believe you are referring specifically to implementation inheritance (i.e. overriding functionality from a parent class) as opposed to interface inheritance (i.e. implementing a consistent interface). This is an important distinction. Implementation inheritance is often hated whereas interface inheritance is often loved (e.g. in F# which has a limited form of ADTs).
You really want both ADTs and interface inheritance. Languages like OCaml and F# offer both.
What is real difference between Class and Structure when you are dealing with Object Oriented Programming. This question is asked many times during my interviews for SE.
Some people says that there is only one difference:
Structure members are public by default and Class members are private by default.
Some says there are many differences.
After reading many articles and forums, I have the following differences:
Classes DEFAULT to having private members. Structures DEFAULT to having public members.
Structures are values type.
Classes are reference type.
Structure stores in memory via stack.
Classes stored in memory via heap.
Structure doesn’t support inheritance.
Classes support inheritance.
Constructor works in different way.
‘new’ operator works in different way.
Allocating memory for structure is very fast because this takes place inline or on the stack.
What are your opinion on my above list or you have a different one. Thanks
This is pretty language-specific. You seem to be mixing a fair share of both C++ and C#, both of which are very different languages (despite superficial similarities in syntax).
In C++ structs indeed default to public member visibility while class defaults to private. In C# struct is used to declare value types which are passed by value (note that the stack allocation is an implementation detail, not a contract).
Generally both languages seem to have the same idea of what struct and class should represent: struct is for simple data structures which do little more than holding data, while classes have state and methods to manipulate it. They are used to build objects in some concrete or abstract sense while data structures are just that: data in a structured form; they don't need to do much with that data or even know what data that is. Essentially they're dumb and don't care.
But that's just how the language designers thought they should be used. People are good at mis-using things so not every struct you see may be a simple, dumb data structure and not every class you see may be a full-blown class with lots of methods and whatnot. It's merely a convention and if people follow it others can look at the code and see "Oh, nice, that's a struct so I don't expect much logic here and move on to more interesting things." It might work ... in theory.
ETA: Since you mentioned in a comment that you are particularly interested in PHP or Java: Both languages do not have any distinction at the syntax or language level of class or struct which is why your question strikes me as a little odd. In both Java and PHP you model things as classes, regardless of whether they are just data structures without logic or actual classes with everything there is.
This is entirely language dependent, so there can be no single correct answer. If you are interested in a specific language, please specify it in your question.
From an OO perspective, there are no difference. They are both types that have a public API with methods (and properties if your language supports them).
From a technical standpoint, there can be many differences, but that depends on the language and/or platform.
When it comes to OO design, I simply choose to ignore that such a thing as a struct exists at all as it gives me no additional capabilities or features. As we dive deeper into the implementation, a class may turn out to be better implemented as a struct, but it's a pure implementation detail.
Difference between Structure and Classes
-The major difference between class and structure is that the declaration of structure
starts with the keyword 'struct' whereas on the other hand, a class starts with the
keyword 'class'.
-In class the data member and member are private by default whereas in structure they
are public by default.
-Data hiding is supported in classes but not in structure.
-Structure deals with variables only whereas objects deal with real-world objects.
-If we explicitly specify the access type of each member, then a structure will behave exactly
as a class.