What is the difference between C structures and Java classes?
I'm a newbie to Java, but somewhat familiar to C. I wanted to know -- what differences are there between C structures and Java objects and invoking their methods? Or are the totally equivalent?
For example, the Bicycle structure:
class BicycleDemo {
public static void main(String[] args) {
// Create two different Bicycle objects
Bicycle bike1 = new Bicycle();
Bicycle bike2 = new Bicycle();
// Invoke methods on those objects
bike1.changeCadence(50);
开发者_开发百科 bike1.speedUp(10);
bike1.changeGear(2);
bike1.printStates();
bike2.changeCadence(50);
bike2.speedUp(10);
bike2.changeGear(2);
bike2.changeCadence(40);
bike2.speedUp(10);
bike2.changeGear(3);
bike2.printStates();
}
}
The reason why I am asking is because they look so similar! Thanks!
If you leave method overriding out of the picture, then you can think of Java classes and methods as a pair of a C-style struct
and a set of functions that operate on those struct
s. For example, if you have a class like this:
public class MyJavaClass {
private int x;
public int getX() {
return x;
}
public int setX(int value) {
x = value;
}
}
This would be similar to writing C code to this effect:
struct MyJavaClass {
int x;
};
int MyJavaClass_getX(struct MyJavaClass* this) {
return this->x;
}
void MyJavaClass_setX(struct MyJavaClass* this, int value) {
this->x = value;
}
The main idea is that a method is similar to a function that takes the receiver object as an implicit "this" parameter. In C, you have to explicitly pass the receiver as a parameter to the function, while in Java this is done implicitly through the object.method()
syntax.
If you start introducing method overriding, this becomes a bit more complicated because the method that you invoke on an object depends on the dynamic type of the object, not the static type. One way of simulating this is using something called a vtable or virtual function table, so named because of C++'s virtual
keyword. The idea is that each object stores a pointer to a table of function pointers, one per function that can be overridden, and when a method is called on the object the appropriate function pointer is selected out of the table and called. So, more properly, the above Java object might look something like this:
struct MyJavaClass_Vtable {
void (*getX)(struct MyJavaClass* this);
void (*setX)(struct MyJavaClass* this, int value);
};
struct MyJavaClass {
struct MyJavaClass_Vtable* vtable;
int x;
};
int MyJavaClass_getX(struct MyJavaClass* this) {
return this->x;
}
void MyJavaClass_setX(struct MyJavaClass* this, int value) {
this->x = value;
}
/* A global instance of the vtable for MyJavaClass */
struct MyJavaClass_Vtable MyJavaClassVtableInstance = {
&MyJavaClass_getX,
&MyJavaClass_setX
};
Whenever you created an instance of MyJavaClass
, you'd set up its vtable doing something like this:
struct MyJavaClass* mjc = malloc(sizeof *mjc);
mjc->vtable = &MyJavaClassVtableInstance;
Then, when invoking a function like this (in Java):
myJavaClass.getX();
In C it would look like
myJavaClass->vtable->getX(myJavaClass);
So in a sense a Java class is just a struct with some extra metainformation. Of course, to the programmer it looks totally different - there's encapsulation, polymorphism, a stricter type system, etc. - but at the level of native code a regular C struct and a Java class probably look very similar.
Hope this helps!
C
struct cannot have methods/functions in it. It is only a collection of different data types. class
can have both variables and methods declared.
A Java class lets you define fields, like a C struct, but has the following additional features:
- As you state in your question, you can add methods to a class which can operate on the data.
- You can declare both fields and methods
private
(and a few other access settings), which means only other methods of the class can access them, not code from outside. (It wouldn't make sense to have this on structs, since there would be no way to access private fields -- this only makes sense when you allow methods). - Classes can inherit from other classes. Among other things, this lets you pass an object of type B where a type A was expected, as long as B inherits from A.
There is another subtle difference. In C, structs are value types but in Java, classes are reference types. That means when you copy a struct in C (such as assigning to a variable or passing as an argument), it gets all of its fields copied, whereas in Java, when you copy a class object, it just copies the reference to the object (so if you modify its fields, you modify the original object as well, not just the copy).
In C, you often use pointers to structs to emulate the reference behaviour of Java. In Java, you don't use pointers because class objects are already references.
The key differences, IMHO are that classes allow
- encapsulation
- polymorphism
These are two very important features of OOP.
精彩评论