|
Thread Rules 1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution. 2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20) 3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible. 4. Use [code] tags to format code blocks. |
On September 27 2016 11:26 travis wrote:Show nested quote +On September 27 2016 09:49 Birdie wrote:It seems they cast their object to the type relatable, which is their interface. Their interface requires that a class have the method isLargerThan(); . But in an interface, isLargerThan(); is empty, to be defined in the implementing class, right? So wtf does casting a random object to the interface type actually do? It doesn't have the isLargerThan(); method. So.. I don't get it. Only classes which implement a particular interface can be cast to that interface. So it isn't a "random" object, it is an object which already implements all the methods in that interface. It says that in that document: "If you define a reference variable whose type is an interface, any object you assign to it must be an instance of a class that implements the interface." In the example given, the Object class must be implementing the Relatable interface (and therefore has a method implementation of isLargerThan). Think of an interface as a contract which the implementing class agrees to follow. The "implement" keyword is the class signing the contract, and the interface's methods are the terms of the contract. The class must follow the contract by creating methods which are the same as the interface's methods. Any class which signs the interface contract can then have the interface's methods called on it, because it guarantees by signing it (with the "implement" keyword) that it will have a version of all the methods in an interface. So then if the Object class is implementing the Relatable interface and therefore has a method implementation of isLargerThan , then what is the point of casting it to that interface type? It already has the method, so what new thing does casting it to the interface type do? What meatpudding said, but to re-state: you can have a whole bunch of classes which all implement Relatable, and then can cast any of those class objects to Relatable and be 100% confident that you can then call isLargerThan on that casted object.
You can have a whole bunch of game characters, for example, and they all implement the Movable interface, so you can loop through all game characters, cast to Movable, and call .move(x, y); on each of them in a single loop.
|
|
I don't get it? I'm not up-to-date on developments in PHP, but the presence of a command to execute an external program in a seperate process seems like a pretty basic capability.
|
On September 27 2016 20:16 Acrofales wrote:I don't get it? I'm not up-to-date on developments in PHP, but the presence of a command to execute an external program in a seperate process seems like a pretty basic capability.
While I created something similar not too long ago myself, PHP's complete lack of multithreading beyond fork() doesn't make it easy to write code that asynchronously calls external programs and still retains access to the program's output. It's basic in pretty much every language that isn't PHP, but PHP, as it tends to do, makes the easy things difficult.
|
On September 27 2016 09:49 Birdie wrote:Show nested quote +It seems they cast their object to the type relatable, which is their interface. Their interface requires that a class have the method isLargerThan(); . But in an interface, isLargerThan(); is empty, to be defined in the implementing class, right? So wtf does casting a random object to the interface type actually do? It doesn't have the isLargerThan(); method. So.. I don't get it. Only classes which implement a particular interface can be cast to that interface. So it isn't a "random" object, it is an object which already implements all the methods in that interface. Thats not exactly true though. This is perfectly valid java code:
Object a = new String("A"); Double b = (Double) a; It compiles without error. Of course, if you actually run this code you will get a ClassCastException.
@travis: An Interface (in java) is a type just like a class or an abstract class. You can not instantiate an interface, but you can use it as the type for a variable. Take the List interface as an example. You could have a method like this:
public static void printList(List aList) { for (Object element : aList) { System.out.println(element); } } This code will print out the contents of any arbitrary list. But you never get an instance of type List because these dont exist. Instead you may get a LinkedList or perhaps an ArrayList (or some other obscure implementations). Using an interface as a type is something completely normal and extremely useful. It takes away the burden of choosing an implementation. Well written code will never actually need to know what List implementation is used. It will always work no matter what kind of List is instantiated. This allows you to swap out the implementation for a better one at any point in time and your code will simply work.
Casting is usually something you should never need to do (except for a few fringe cases). People still do it plenty of times, usually out of laziness. Writing code without casting often requires much more work when you can do a simple solution by typecasting. Even the java code examples and tutorials from the oracle website use typecasting an egregious number of times. Many of these typecasts could have easily been avoided with better written code.
|
Let me first introduce myself briefly. I am a mechanical engineering graduate who'd like to learn some Python and MATLAB programming, because I consider programming an important skill in every engineer's repertoire. For the past two months I have studied both languages and worked on some private projects of mine since that seems to be the best way to learn useful things.
I'm currently working on a MATLAB program that is supposed to quantify the degree of banding in the microstructures I simulated with an earlier script (the output is basically a set of (x,y) coordinates), and I've encountered some performance issues when compared with the program whose analysis I am trying to recreate (PASSaGE, link below).
My understanding of how the analysis is supposed to work is based on the paper written by the software's author (link) and the program's manual, but some sections were quite misleading in my opinion, so I had to do several modifications based on some experiments with analysis.
http://www.passagesoftware.net/
http://rosenberglab.net/Pubs/JVegSci2004v15p277.pdf
Initially, my MATLAB script took roughly 15 minutes (more specifically, the function that runs the analysis, not the overarching script) to analyze a set of 1000 points, whereas PASSaGE takes around 1-2 minutes. It relied mostly on loops. After a few days of optimizing, I managed to decrease the calculation time to 160-170 seconds, but I seem to have hit a dead end.
Here's the overarching script (just in case):
+ Show Spoiler +clc clear
%%% PARAMETERS %%%
answer = input('Should the default value be used for the edge region parameter? Y/N [Y]: ','s'); if isempty(answer) % If the user simply presses 'Enter', the answer is assumed to be 'Y'. answer = 'Y'; end
disp(' ') % Empty line for clarity.
if strcmp(answer, 'Y') == 1 edge_parameter = 0.25; disp('The default value of the edge region parameter (0.25) will be used.') else edge_parameter = input('Please, specify the value of the edge region parameter: '); end
%%% IMPORT OF DATA %%%
filename = 'banding_coordinates.txt'; delimiterIn = ' '; headerlinesIn = 1; D = importdata(filename,delimiterIn,headerlinesIn);
%%% EXTRACTION OF COORDINATES %%%
x_extracted = D.data(:,1); y_extracted = D.data(:,2);
% Transposition into vectors:
x = transpose(x_extracted); y = transpose(y_extracted);
% Verification of vector lengths:
if length(x) ~= length(y) disp('The imported data is corrupted: the numbers of the x and y coordinates do not match') end
%%% BOUNDARY CONDITIONS %%%
% Limits of the analyzed space:
x_min = min(x); x_max = max(x); y_min = min(y); y_max = max(y);
% Edge region parameters for each coordinate:
edge_parameter_x = edge_parameter*(x_max - x_min); edge_parameter_y = edge_parameter*(y_max - y_min);
% Limits of the focal point space:
x_foc_min = x_min + edge_parameter_x; x_foc_max = x_max - edge_parameter_x; y_foc_min = y_min + edge_parameter_y; y_foc_max = y_max - edge_parameter_y;
%%% EXTRACTION OF FOCAL POINTS %%%
% Generation of focal points:
[in,on] = inpolygon(x, y, [x_foc_min, x_foc_max], [y_foc_min, y_foc_max]);
x_foc = x(in); y_foc = y(in);
% Focal points plot:
answer = input('Would you like to display the generated focal points? Y/N [N]: ','s'); if isempty(answer) % If the user simply presses 'Enter', the answer is assumed to be 'Y'. answer = 'N'; end
disp(' ') % Empty line for clarity.
if strcmp(answer, 'Y') == 1 figure
scatter(x,y,'.') % all points axis equal
hold on scatter(x_foc,y_foc,'r+') % focal points hold off end
%%% ANALYSIS %%% tic overall_variance = calculate_variance_test6_3(x, y, x_foc, y_foc, ... x_min, x_max, y_min, y_max); toc %%% OUTPUT %%%
% Original variance peak:
disp('Original variance peak:') max(overall_variance)
% Plot:
figure
plot(1:1:180, overall_variance)
And here's the function that does the actual analysis (in its most optimal form):
+ Show Spoiler +function variance_avg_foc = calculate_variance_test6_3(x, y, x_foc, y_foc, ... x_min, x_max, y_min, y_max)
% Calculation of the number of focal points:
m = length(x_foc); % Number of focal points = number of iterations in the first loop.
% Calculation of the number of scales:
scale = 1:1:45; % All scales. l = length(scale);
% Preallocation of memory for all focal points:
variance_avg_scale = zeros(m, 180); % Calculation of the number of analyzed points: n = length(x) - 1; % Calculation of transect properties:
p = 1:1:180; transect_angles = p - 1; slopes = tand((transect_angles)); % Selection of the focal point
for j = 1:m % Removal of the focal point from the pool of analyzed points: index = find( (x(1,:) == x_foc(j)) & (y(1,:) == y_foc(j)) ); if length(index) ~= 1 % If there is more than once point with the x_foc(j), y_foc(j) index = index(1); % coordinates, only one point will be subtracted from the future end % local coordinates pool. x_without_foc = x(1:end ~= index); y_without_foc = y(1:end ~= index); % Creation of local coordinates /vectorized:
i = 1:1:n; % One iteration for each (x, y) point. x_local = x_without_foc(i) - x_foc(j); y_local = y_without_foc(i) - y_foc(j);
% Limits of the studied area in local coordinates: x_min_local = x_min - x_foc(j); x_max_local = x_max - x_foc(j); y_min_local = y_min - y_foc(j); y_max_local = y_max - y_foc(j); % Translation to local polar coordinates:
[angle,radius] = cart_to_pol(x_local,y_local); angle = rad2deg(angle); % Consolidation of coordinates data:
data = [angle; radius];
% Preallocation of memory for all scales:
transect_area = zeros(1, 180); % Calculation of the transect area: for p = 1:180 transect_angle = transect_angles(p); slope = slopes(p); transect_area(p) = calculate_transect_area(x_min_local, ... x_max_local, y_min_local, y_max_local, transect_angle, slope); end % Preallocation of memory for all scales:
variance_scale = zeros(l, 180);
% Selection of scale:
for k = 1:l
% Transect width: transect_width = scale; % Preallocation of memory for all positions:
wavelet_transform = zeros(1, 180); variance_normalized = zeros(1, 180);
% Selection of angular position:
for p = 1:180 % Finding the points inside the specified transect:
points_observed = observe_points(data, p, transect_width(k));
% Extraction of the polar coordinates of the observed points:
angle_observed = points_observed(1,:); radius_observed = points_observed(2,:);
% Calculation of the number of observed points:
observations = length(angle_observed); % Calculation of scaled wavelets for each point within the transect /vectorized:
if observations == 0 scaled_wavelet = 0; else o = 1:1:observations; t = (angle_observed(o) - transect_angles(p))./scale(k); scaled_wavelet = radius_observed.*wavelet_function(t); end wavelet_transform(p) = sum(scaled_wavelet)/scale(k); variance_normalized(p) = wavelet_transform(p)^2/transect_area(p); end variance_scale(k,:) = variance_normalized; end variance_avg_scale(j,:) = sum(variance_scale)./l; % All specified scales. end variance_avg_foc = sum(variance_avg_scale)./m; end
%-------------------------------------------------------------------------- function [angle, radius] = cart_to_pol(x, y)
angle = arctan(y, x); radius = hypot(x,y);
end
%-------------------------------------------------------------------------- function angle = arctan(y, x) n = length(x); angle = zeros(1, n); parfor i = 1:n % /vectorized angle(i) = atan2(y(i), x(i)); if angle(i) < 0 angle(i) = angle(i) + pi; end end end
%-------------------------------------------------------------------------- function points_observed = observe_points(data, p, transect_width)
% Finding the points inside the specified transect:
step_size = 1;
log_ind = ( (p - 1 - (transect_width/2))*step_size <= data(1,:) & ... data(1,:) <= (p - 1 + (transect_width/2))*step_size ) | ... ( ((p - 1 - (transect_width/2))*step_size + 180) <= data(1,:) & ... data(1,:) <= ((p - 1 + (transect_width/2))*step_size + 180) ); points_observed = data(:,log_ind);
end
%-------------------------------------------------------------------------- function transect_area = calculate_transect_area(x_min_local, ... x_max_local, y_min_local, y_max_local, transect_angle, slope) % Slope variants: if (transect_angle == 0) || (transect_angle == 180) % Horizontal line. x_lim_1 = x_min_local; x_lim_2 = x_max_local; y_lim_1 = 0; y_lim_2 = 0; elseif transect_angle == 90 % Vertical line. x_lim_1 = 0; x_lim_2 = 0; y_lim_1 = y_min_local; y_lim_2 = y_max_local; elseif transect_angle > 0 && transect_angle < 90 % Boundary coordinates:
if y_min_local/slope >= x_min_local x_lim_1 = y_min_local/slope; y_lim_1 = y_min_local; else x_lim_1 = x_min_local; y_lim_1 = slope*x_min_local; end
if y_max_local/slope <= x_max_local x_lim_2 = y_max_local/slope; y_lim_2 = y_max_local; else x_lim_2 = x_max_local; y_lim_2 = slope*x_max_local; end else
% Boundary coordinates:
if y_min_local/slope >= x_max_local x_lim_1 = x_max_local; y_lim_1 = slope*x_max_local; else x_lim_1 = y_min_local/slope; y_lim_1 = y_min_local; end
if y_max_local/slope <= x_min_local x_lim_2 = x_min_local; y_lim_2 = slope*x_min_local; else x_lim_2 = y_max_local/slope; y_lim_2 = y_max_local; end end transect_area = (x_lim_1)^2 + (y_lim_1)^2 + (x_lim_2)^2 + (y_lim_2)^2; % This is not real area of the transect. % It's area divided by omega/2, but that holds % for all transects and omega is constant. end
%-------------------------------------------------------------------------- function mexican_hat = wavelet_function(t) % /vectorized
mexican_hat = 2./(sqrt(3)).*pi.^(-1/4).*(1 - 4.*t.^2).*exp(-2.*t.^2); % Wavelet function normalized to have unit energy. % Vectorizing with "vectorize()" does not work. % It cannot tell if I want to use ^ for matrices (mpower) % or scalars (power). end
According to the MATLAB profiler, there are two lines/functions whose vectorization could yield significant improvements in calculation time, but I failed at vectorizing them properly... Any help would be appreciated.
This line currently requires roughly 95 seconds (it's being called 4 million times):
+ Show Spoiler +points_observed = observe_points(data, p, transect_width(k));
And these two lines require roughly 30 seconds (they're being called 700 thousand times):
+ Show Spoiler +t = (angle_observed(o) - transect_angles(p))./scale(k); scaled_wavelet = radius_observed.*wavelet_function(t);
Additionally, I am looking for a way to make scaled_wavelet call wavelet_function only for non-zero values of radius_observed. I tried the solution below, but it only made the calculations longer:
+ Show Spoiler +% Calculation of scaled wavelets for each point within the transect /vectorized:
if observations == 0 scaled_wavelet = 0; else log_ind = (radius_observed ~= 0); %o = 1:1:observations; scaled_wavelet = radius_observed(log_ind).*wavelet_function((angle_observed(log_ind) - transect_angles(p))./scale(k)); end
I also found that spfun() does something similar, but I don't know how to make it work with a custom function like wavelet_function().
|
On September 27 2016 22:44 RoomOfMush wrote:Show nested quote +On September 27 2016 09:49 Birdie wrote:It seems they cast their object to the type relatable, which is their interface. Their interface requires that a class have the method isLargerThan(); . But in an interface, isLargerThan(); is empty, to be defined in the implementing class, right? So wtf does casting a random object to the interface type actually do? It doesn't have the isLargerThan(); method. So.. I don't get it. Only classes which implement a particular interface can be cast to that interface. So it isn't a "random" object, it is an object which already implements all the methods in that interface. Thats not exactly true though. This is perfectly valid java code: Object a = new String("A"); Double b = (Double) a; It compiles without error. Of course, if you actually run this code you will get a ClassCastException. @travis: An Interface (in java) is a type just like a class or an abstract class. You can not instantiate an interface, but you can use it as the type for a variable. Take the List interface as an example. You could have a method like this: public static void printList(List aList) { for (Object element : aList) { System.out.println(element); } } This code will print out the contents of any arbitrary list. But you never get an instance of type List because these dont exist. Instead you may get a LinkedList or perhaps an ArrayList (or some other obscure implementations). Using an interface as a type is something completely normal and extremely useful. It takes away the burden of choosing an implementation. Well written code will never actually need to know what List implementation is used. It will always work no matter what kind of List is instantiated. This allows you to swap out the implementation for a better one at any point in time and your code will simply work. Casting is usually something you should never need to do (except for a few fringe cases). People still do it plenty of times, usually out of laziness. Writing code without casting often requires much more work when you can do a simple solution by typecasting. Even the java code examples and tutorials from the oracle website use typecasting an egregious number of times. Many of these typecasts could have easily been avoided with better written code.
As you said yourself, that throws a ClassCastException at runtime. If (warning: completely nonsense example) your String class implemented the Double interface, then that would NOT throw a classcastexception, and all the operations defined in your interface would be guaranteed to be implemented. THAT is the point of an interface. Also, this:
List<Double> foo = new ArrayList<Double>(); foo.add(new String("a");
does not compile (and while you can cast that to double and have it only bomb out at runtime, that is some willfully stupid programming; it's of the quality "it compiles, therefore it works flawlessly".
So, in effect, the statement "only classes that implement that interface can be cast to it" is correct, and the fact that it is a runtime error, rather than a compiler error is not a counterargument. As you said yourself, using casts (for this type of thing, as I disagree that casts are categorically bad) is not a good style.
It used to be the case in Java (pre-1.5, I think, but it might have been 6) that Java didn't have generics, and collections contained, by default, objects of class Object. That was a pain in the ass. Java generics have their foibles, but they are a vast improvement over their absense. However, your example is a bad one, because it doesn't depend on interfaces at all. It is predicated upon the fact that the Object class in Java is, by definition, a superclass of every single other class. Object isn't an interface, it is a class. A better example would be the very common interfaces like Serializable, Runnable, or EventListener.
Not only that, but the absense of generics means your code will give a nasty warning (due to the absense of said generics).
PS. Nasty warnings are technically warnings just like all other warnings, but ones that indicate something seriously wrong with your code if you ignore them: you are either an experienced programmer who is willfully ignoring said warning, or you had better fix that shit. While an argument can be made that ALL warnings are of that type, my opinion is that the Java compiler goes a bit overboard on the warnings.
|
On September 27 2016 23:10 Acrofales wrote: So, in effect, the statement "only classes that implement that interface can be cast to it" is correct, and the fact that it is a runtime error, rather than a compiler error is not a counterargument. As you said yourself, using casts (for this type of thing, as I disagree that casts are categorically bad) is not a good style. No, its not correct. You are confusing classes with objects. You never cast classes, you may cast references of certain types though. You can cast a reference of any type to any other type. What you can not do is cast an object to a wrong type. The difference between classes, references and objects is important. Maybe you think I am being pedantic, but I am actually teaching this stuff to first semester CS students and so I am always very careful of using the wrong terms.
On September 27 2016 23:10 Acrofales wrote: It used to be the case in Java (pre-1.5, I think, but it might have been 6) that Java didn't have generics, and collections contained, by default, objects of class Object. That was a pain in the ass. This is also wrong. Collections did always contain objects of any arbitrary type. The difference is that the collections of old only ever returned references of type Object, but the actual objects that were returned could have been anything. The fun fact is: The generic collections of today STILL only hold references to the Object class. They simply do a class cast internally when you call a get method. Generics in java are only a simple form of static code analysis. At runtime they are completely gone and replaced by Object references. This is why you can not declare arrays of generic type parameters in java.
On September 27 2016 23:10 Acrofales wrote: Java generics have their foibles, but they are a vast improvement over their absense. However, your example is a bad one, because it doesn't depend on interfaces at all. It is predicated upon the fact that the Object class in Java is, by definition, a superclass of every single other class. Object isn't an interface, it is a class. A better example would be the very common interfaces like Serializable, Runnable, or EventListener.
Not only that, but the absense of generics means your code will give a nasty warning (due to the absense of said generics).
PS. Nasty warnings are technically warnings just like all other warnings, but ones that indicate something seriously wrong with your code if you ignore them: you are either an experienced programmer who is willfully ignoring said warning, or you had better fix that shit. While an argument can be made that ALL warnings are of that type, my opinion is that the Java compiler goes a bit overboard on the warnings. I left out generics in my example because I dont know how much travis knows. Perhaps he didnt learn about generics yet in which case they would only confuse him instead of helping him understand the issue.
|
On September 27 2016 22:57 maybenexttime wrote: Let me first introduce myself briefly. I am a mechanical engineering graduate who'd like to learn some Python and MATLAB programming, because I consider programming an important skill in every engineer's repertoire. For the past two months I have studied both languages and worked on some private projects of mine since that seems to be the best way to learn useful things.
.
Heh. Strange coincidence i am also mechanical engineer (material engineering to be precise) and Python also is my langauge of choice (and also Polish ). I cant help You with MATHLAB though, never had time to learn it properly. Will try to help with Python if i can though.
BTW Which Uni did You gradute from?
|
On September 28 2016 00:47 Silvanel wrote:Show nested quote +On September 27 2016 22:57 maybenexttime wrote: Let me first introduce myself briefly. I am a mechanical engineering graduate who'd like to learn some Python and MATLAB programming, because I consider programming an important skill in every engineer's repertoire. For the past two months I have studied both languages and worked on some private projects of mine since that seems to be the best way to learn useful things.
. Heh. Strange coincidence i am also mechanical engineer (material engineering to be precise) and Python also is my langauge of choice (and also Polish  ). I cant help You with MATHLAB though, never had time to learn it properly. Will try to help with Python if i can though. BTW Which Uni did You gradute from?
Strangely enough, I specialized in structural materials engineering. 
I graduated from Wrocław University of Technology/Politechnika Wrocławska. And you? :-)
|
Am I correct in thinking that an abstract class is basically an "inbetween" of an interface and a superclass ?
also thank you for everyone who takes time to reply to me. I may not reply to them or just haven't read them yet but I do go over them.
|
On September 28 2016 01:50 travis wrote: Am I correct in thinking that an abstract class is basically an "inbetween" of an interface and a superclass ?
An abstract class can contain implemented methods and other data unlike the interface which only has method stubs. The difference between these two things is an actual thing in java as they have different name and are used by the subclass through different keywords. If you look at another language like php you will see that the line is more blurred and there is almost no difference between the two terms.
You are correct in thinking they are similar.
|
On September 27 2016 11:26 travis wrote:Show nested quote +On September 27 2016 09:49 Birdie wrote:It seems they cast their object to the type relatable, which is their interface. Their interface requires that a class have the method isLargerThan(); . But in an interface, isLargerThan(); is empty, to be defined in the implementing class, right? So wtf does casting a random object to the interface type actually do? It doesn't have the isLargerThan(); method. So.. I don't get it. Only classes which implement a particular interface can be cast to that interface. So it isn't a "random" object, it is an object which already implements all the methods in that interface. It says that in that document: "If you define a reference variable whose type is an interface, any object you assign to it must be an instance of a class that implements the interface." In the example given, the Object class must be implementing the Relatable interface (and therefore has a method implementation of isLargerThan). Think of an interface as a contract which the implementing class agrees to follow. The "implement" keyword is the class signing the contract, and the interface's methods are the terms of the contract. The class must follow the contract by creating methods which are the same as the interface's methods. Any class which signs the interface contract can then have the interface's methods called on it, because it guarantees by signing it (with the "implement" keyword) that it will have a version of all the methods in an interface. So then if the Object class is implementing the Relatable interface and therefore has a method implementation of isLargerThan , then what is the point of casting it to that interface type? It already has the method, so what new thing does casting it to the interface type do?
If you already know that, nothing. E.g. if you know you have a Double, you don't have to cast it to a Relatable to call isLargerThan. But look at the implementation of isLargerThan. It requires a parameter of type Relatable. It doesn't care whether that is a double, a different type of number, or a string.
As another example, consider Serializable. For this, you technically don't even have to implement anything, you just declare that the class implements Serializable. Because of inheritance, you can call serialize() on your objects of this type (the Object class gives a default implementation of the serialize method). However everything that does things for which objects need to be serialized (like read/writing them to file, or sending it over the network), wanted an object of type Serializable, and not of type Object, because one can assume that if you implement the interface, you have thought a bit about how your class should be serialized, and if the default implementation doesn't suffice, have provided your own implementation. It makes debugging easier too, because if you try to do something with an object that is not Serializable, you get a decent error, instead of it writing nonsense to a file, and then breaking at some random point in the future to a null pointer, after deserializing the object from file.
|
On September 28 2016 01:50 travis wrote: Am I correct in thinking that an abstract class is basically an "inbetween" of an interface and a superclass ?
also thank you for everyone who takes time to reply to me. I may not reply to them or just haven't read them yet but I do go over them. Since java 8 the only difference between an abstract class and an interface is the fact that the abstract class can have fields and it can override methods from the Object class. Interfaces can not override methods from Object, like toString, equals and hashCode which makes sense from a technical point of view but is quite a bummer from a practical point of view. Another difference is that abstract classes can not be used for lambdas but interfaces can. I dont know if you have learned about lambdas yet but they have become a big deal in java 8.
|
On September 28 2016 02:01 Blitzkrieg0 wrote:Show nested quote +On September 28 2016 01:50 travis wrote: Am I correct in thinking that an abstract class is basically an "inbetween" of an interface and a superclass ? An abstract class can contain implemented methods and other data unlike the interface which only has method stubs. The difference between these two things is an actual thing in java as they have different name and are used by the subclass through different keywords. If you look at another language like php you will see that the line is more blurred and there is almost no difference between the two terms. You are correct in thinking they are similar. And if you look at polymorphism in Android, the line is equally blurred, because often the documentation specifies that if you implement a specific interface, you need to implement a specific field, as well as the methods, but interfaces don't allow one to specify that. In other words, interfaces are being used for multiple inheritance in Android in a very similar way that abstract classes are in other languages.
|
On September 28 2016 02:03 Acrofales wrote:Show nested quote +On September 27 2016 11:26 travis wrote:On September 27 2016 09:49 Birdie wrote:It seems they cast their object to the type relatable, which is their interface. Their interface requires that a class have the method isLargerThan(); . But in an interface, isLargerThan(); is empty, to be defined in the implementing class, right? So wtf does casting a random object to the interface type actually do? It doesn't have the isLargerThan(); method. So.. I don't get it. Only classes which implement a particular interface can be cast to that interface. So it isn't a "random" object, it is an object which already implements all the methods in that interface. It says that in that document: "If you define a reference variable whose type is an interface, any object you assign to it must be an instance of a class that implements the interface." In the example given, the Object class must be implementing the Relatable interface (and therefore has a method implementation of isLargerThan). Think of an interface as a contract which the implementing class agrees to follow. The "implement" keyword is the class signing the contract, and the interface's methods are the terms of the contract. The class must follow the contract by creating methods which are the same as the interface's methods. Any class which signs the interface contract can then have the interface's methods called on it, because it guarantees by signing it (with the "implement" keyword) that it will have a version of all the methods in an interface. So then if the Object class is implementing the Relatable interface and therefore has a method implementation of isLargerThan , then what is the point of casting it to that interface type? It already has the method, so what new thing does casting it to the interface type do? If you already know that, nothing. E.g. if you know you have a Double, you don't have to cast it to a Relatable to call isLargerThan. But look at the implementation of isLargerThan. It requires a parameter of type Relatable. It doesn't care whether that is a double, a different type of number, or a string. As another example, consider Serializable. For this, you technically don't even have to implement anything, you just declare that the class implements Serializable. Because of inheritance, you can call serialize() on your objects of this type (the Object class gives a default implementation of the serialize method). However everything that does things for which objects need to be serialized (like read/writing them to file, or sending it over the network), wanted an object of type Serializable, and not of type Object, because one can assume that if you implement the interface, you have thought a bit about how your class should be serialized, and if the default implementation doesn't suffice, have provided your own implementation. It makes debugging easier too, because if you try to do something with an object that is not Serializable, you get a decent error, instead of it writing nonsense to a file, and then breaking at some random point in the future to a null pointer, after federalizing the object from file. Its a good thing that you are trying to help people but please fact check what you say before hand. There is no "serialize()" method and Object certainly doesnt define it. And methods that are used in object serialization do not take Serializable as arguments (even though they should). They actually just take Object and instead state in their JavaDoc that a runtime exception is thrown in case the object is not serializable. Serializable is a really bad example for the use of interfaces because it actually uses Reflection instead.
|
So from what I have read, if I have a method in a superclass and it has a return type I can change the return type of the overrided method to a different return type, as long as it's a subclass of the original return type?
like, I can't go from int to string but I can go from Integer to int ?
and I am assuming this means I couldn't go from a return type to void in my overriden method?
And then my next question is about overloading. Overloaded methods must all have the same access level and return type? Only the parameters change? Will I get errors if I try to make methods with the same name but different return types or access levels?
edit: all questions are specific to java since that is what my exam will be on
|
On September 28 2016 02:18 travis wrote: So from what I have read, if I have a method in a superclass and it has a return type I can change the return type of the overrided method to a different return type, as long as it's a subclass of the original return type?
like, I can't go from int to string but I can go from Integer to int ?
and I am assuming this means I couldn't go from a return type to void in my overriden method? What you say is correct but your example is wrong. int is not a subclass of Integer (nor is it the other way around). "int" is not a class at all, its a primitive data type which is something completely seperate from classes. You are still allowed to use "int" and "Integer" almost interchangeably but that has nothing to do with class hierarchy. This is actually compiler magic called "boxing" and "unboxing".
But if your super class has a method named test() which returns Object you can have a subclass with a method named test() which returns String because String is a subclass of Object. Think about it like this: Every String IS an Object. If your method is supposed to return an Object but it returns a String then it IS actually returning an Object like it is supposed to do.
On September 28 2016 02:18 travis wrote: And then my next question is about overloading. Overloaded methods must all have the same access level and return type? Only the parameters change? Will I get errors if I try to make methods with the same name but different return types or access levels?
edit: all questions are specific to java since that is what my exam will be on Overloaded methods do not need to have the same access level at all. They also dont need to have the same return type. There is no overloading in the Java specification. The compiler does not care about overloading; for the compiler two methods with the same name but different parameter lists are simply 2 different methods. Edit: Just quoting the specification: (Source)
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded.
This fact causes no difficulty and never of itself results in a compile-time error. There is no required relationship between the return types or between the throws clauses of two methods with the same name, unless their signatures are override-equivalent.
The nice thing about these kinds of questions is: You dont have to ask. Just try it out. Grab a text editor and a java compiler, type in an example and see whether it will compile or not. Example:
public class OverloadingExample { public String test() { return "1984"; } public Integer test(int param) { return 42; } public String test(double param) { return "4891"; } } (^This compiles perfectly fine for example)
|
On September 28 2016 01:08 maybenexttime wrote:Show nested quote +On September 28 2016 00:47 Silvanel wrote:On September 27 2016 22:57 maybenexttime wrote: Let me first introduce myself briefly. I am a mechanical engineering graduate who'd like to learn some Python and MATLAB programming, because I consider programming an important skill in every engineer's repertoire. For the past two months I have studied both languages and worked on some private projects of mine since that seems to be the best way to learn useful things.
. Heh. Strange coincidence i am also mechanical engineer (material engineering to be precise) and Python also is my langauge of choice (and also Polish  ). I cant help You with MATHLAB though, never had time to learn it properly. Will try to help with Python if i can though. BTW Which Uni did You gradute from? Strangely enough, I specialized in structural materials engineering.  I graduated from Wrocław University of Technology/Politechnika Wrocławska. And you? :-)
Technical University of Łódź
|
edit: nevermind I need to go over enums better they are confusing actually
aaand - I figured it out. I needed to make an array of the type of my enum and assign it to that enum.values() in order to use a for each loop to go through them
|
|
|
|