Overwrite method inside an objective-c class as in Java - java

I often use this statement for extending class without needs of writing a whole separate file. Supposing ClassFromFramework is a class being part of a framework included in library.
public ClassFromFramework {
public String myMethod() {
// operations
}
//lot of other methods....
}
Then in my class I could do the following:
import com.framework.ClassFromFramework;
public MyClass {
public void method() {
ClassFromFramework m = new ClassFromFramework() {
#Override
public String myMethod() {
// do operations...
}
}
m.myMethod();
}
}
I wonder if I can achieve the same with Objective-c without declaring a new combination .h .m files and import in my using class.

You can make a new subclass, and override methods, but all new classes must be in their own .h & .m files. That's how Obj-C operates. In this case, it would make sense to have the additional files.
You can also call the parent method with the word super. This is done all the time when subclassing a ViewController, such as in viewDidLoad.

Related

Design Approach and Using Reflection to run methods in Java

I have a question. I have multiple classes in a package: Let's say package is
com.myPackage.first
And this package has the following classes:
firstGood
secondGood
thirdBad
fourthGood
Each of these classes have a method with the same name but different implementation. So say each have a one particular function called:
public void runMe(){
}
For now I want to come up with a way to given a class name, it'll go inside the class and run that particular method.
So conceptually, my method will look like those:
ArrayList<Class> classList ; // where classList is a list of classes I want to run
public void execute(){
for(Class c : classList){
// Go inside that class, (maybe create an intance of that class) and run the method called run me
}
}
or
public void execute(Class c, String methodToRun){
for(Class c : classList){
// Go inside that class, (maybe create an intance of that class) and run the method called run me
}
}
For now. what I have been able to do is get the name of the classes I want to run the
runMe()
method. So I have been able to come with a way to get the arraylist of classes I want to run. So what I need help with is coming up with a method such that it takes a class name and run the method I want it to. Any help is appreciated. Thanks
I suggest having a look at Class.forName ( ... ) to get the class object, Class.newInstance(); if your classes have a default constructor (or Class.getDeclaredConstructor(...) otherwise) to create a new instance and then Class.getDeclaredMethod( ... ) to find the method and invoke it.
All of this without any regard if your idea is really a good one, since I really didn't quite understand WHY you want to do what you want to do...
interface Me {
void runMe();
}
Then let all classes implement Me.
And have a list of Mes
List<Class<Me>> ...
Then
void test(Class<Me> cl) {
Me me = cl.newInstance();
me.runMe();
}
My adage is always use reflection to solve a problem - now you have two problems. In view of that have you considered a simple pattern like this:
interface Runner {
public void runMe();
}
static abstract class BaseRunner implements Runner {
public BaseRunner() {
// Automagically register all runners in the RunThem class.
RunThem.runners.add(this);
}
}
class FirstGood extends BaseRunner implements Runner {
#Override
public void runMe() {
System.out.println(this.getClass().getSimpleName() + ":runMe");
}
}
class SecondGood extends BaseRunner implements Runner {
#Override
public void runMe() {
System.out.println(this.getClass().getSimpleName() + ":runMe");
}
}
static class RunThem {
static final Set<Runner> runners = new HashSet<>();
static void runThem() {
for (Runner r : runners) {
r.runMe();
}
}
}
public void test() {
Runner f = new FirstGood();
Runner s = new SecondGood();
RunThem.runThem();
}
Here all of your runMe objects extend a base class whose constructor installs the object in a Set held by the class that calls their runMe methods.
inline
void execute() throws Exception{
for (Class<?> c : classesList)
{
//If you don't already have an instance then you need one
//note if the method is static no need for any existing instance.
Object obj = Class.forName(c.getName());
// name of the method and list of arguments to pass
Method m = c.getDeclaredMethod(methodName,null);
//method accessibility check
if(!m.isAccessible())
m.setAccessible(true);
//invoke method if method with arguements then pass them as new Object[]{arg0...} instead of null
//if method is static then m.innvoke(null,null)
m.invoke(obj, null);
}
}
I would recommend using an Interface that defines the runMe() method and then have all your classes implement that interface. Then you would have a list of this Interface:
List<MyInterface> classes = new ArrayList<MyInterface>();
Then you could easily iterate over it and invoke "runMe()" on all of them or if you only want to invoke it for instances of a certain class you could do it like this:
public void execute(Class classForWhichToExecute) {
for (MyInterface myInterface : classes) {
if (classForWhichToExecute.isAssignableForm(myInterface)) {
myInterface.runMe();
}
}
}
Of course this wouldn't work if your method is a static method - so adding more information from your side would help.
I would suggest to use an interface with a common method to override in each class. So that any class can be casted to interface and use its method to execute the method.
interface GoodAndBad{
public void runMe();
}
Implemented class
class FirstGood implements GoodAndBad{
#override
public void runMe(){
// Code to be executed
}
}
You can use execute() method as follows
public void execute(List<GoodAndBad> classList){
for(GoodAndBad c : classList){
c.runMe();
// Go inside that class, (maybe create an intance of that class) and
// run the method called run me
}
}
Change the Class to GoodAndBad interface to change the other method too.
This is loosely coupling objects to support favor over composition in Java Object Oriented Design Patterns.
Never use Strings of method names to execute a method at anytime. There are plenty of other cool solutions for that using design patterns.

Inner classes with the same name as an outer class?

Constraints:
I have a maven source code generator that I wrote that is creating POJO classes
from some data files that have nested namespaces. I want each namespace to
be nested as an inner class. In some cases out of my control I end up
with inner classes that are the same simple name as the outermost
class.
All the classes must be public scope as this is for a type safe
wrapper over something like a properties file, but hierarchical..
I can't change the names otherwise I am changing the names meaning and the namespace
that is enclosing data.
Given than I have the following code:
public class A
{
public class B
{
public class A
{
}
}
}
Inner classes should append the name of the outer class to form a unique namespace such as A$B$A.class, I haven't found a valid reason for this not to compile.
Is there any trick to get this to compile?
No. From the JLS section on class declarations:
It is a compile-time error if a class has the same simple name as any of its enclosing classes or interfaces.
Note: I somehow managed to miss this on my first pass through looking for an explicit rule. Check the edit history if you want the tortuous way I got here.
You asked: Is there any trick to get this to compile?.
The answer is: Well, maybe....
Create a class like the following:
public class A
{
public class B
{
public class X
{
}
}
}
And a class where this class is going to be used
public class AUse
{
public static void main(String[] args)
{
A.B.X aba = new A().new B().new X();
System.out.println("Created "+aba+" of class "+aba.getClass());
}
}
Then, download the Apache Byte Code Engineering Library (BCEL), and create and run the following class:
import java.io.FileOutputStream;
import org.apache.bcel.Repository;
import org.apache.bcel.util.BCELifier;
public class CreateCreators
{
public static void main(String[] args) throws Exception
{
new BCELifier(
Repository.lookupClass("A"),
new FileOutputStream("ACreator.java")).start();
new BCELifier(
Repository.lookupClass("A$B"),
new FileOutputStream("A$BCreator.java")).start();
new BCELifier(
Repository.lookupClass("A$B$X"),
new FileOutputStream("A$B$XCreator.java")).start();
new BCELifier(
Repository.lookupClass("AUse"),
new FileOutputStream("AUseCreator.java")).start();
}
}
This uses the BCELifier class from the BCEL. This is a class that takes a .class file, and creates a .java file that can be compiled to a .class file, that, when it is executed, creates the .class file that it was originally fed with. (Side note: I love this library).
So the A$B$XCreator.java file that is created there contains the BCEL code that is necessary to create the A$B$X.class file. This consists of statements like the generation of the constant pool and the instructions:
...
_cg = new ClassGen("A$B$X", "java.lang.Object", "A.java",
ACC_PUBLIC | ACC_SUPER, new String[] { });
...
il.append(_factory.createFieldAccess("A$B$X", "this$1",
new ObjectType("A$B"), Constants.PUTFIELD));
Similarly, the AUseCreator.java contains the BCEL code that creates the AUse.class. For example, the instruction of the constructor invocation of `A$B$X':
...
il.append(_factory.createInvoke("A$B$X", "<init>", Type.VOID,
new Type[] { new ObjectType("A$B") }, Constants.INVOKESPECIAL));
Now you can simply replace the String occurrences of "A$B$X" with "A$B$A" in the A$B$XCreator.java and AUseCreator.java, and then compile and run these classes.
The result will be a A$B$A.class file, and a AUse.class file that uses the A$B$A.class. Executing the AUse will print
Created A$B$A#15f5897 of class class A$B$A
I'm not sure whether this is considered as a "trick", or whether it still can be called "compiling" at all, but there is a way, at least. The key point is here, of course, that the fact that it did not compile is solely due to a limitation of the language, but there is no reason why this should not be representable in form of class files, regardless of how they are created.
You can't get it to compile, but more importantly, why would you need to?
What's wrong with:
public class A
{
public class B
{
public class InnerA
{
}
}
}
This seems like a design problem that you need to fix. If you can't rename it, consider anonymous inner classes. Or take some of those classes outside. Or just don't even use them.
It's a bit of a hack, but this compiles at my machine:
class A
{
public class B
{
public class Α
{
}
}
}
Try it. Literally: copy-past this thing ;)
SPOILER:
The name of the inner class is a capital letter alpha of the Greek alphabet. It's a Unicode character.
Depending on what you're after, the following might work for you:
public class A {
class B extends C {
}
public static void main(String[] args) {
new A().new B().new A();
}
}
class C {
class A {
{
System.out.println(getClass());
}
}
}

cannot combine two classes java

I have these two classes that I want to combine into a single file but i don't know how.
import java.util.LinkedList;
public class BFSolver{
public static boolean[][] didVisit;
public static LinkedList<Pair> expanded ;
public BFSolver() {
}
the other class looks something like this:
import java.util.LinkedList;
public class DFSolver{
public static boolean[][] didVisit;
public static LinkedList<Pair> expanded = new LinkedList<Pair>();
public DFSolver() {
}
when I put the import statments in one file
and the classes declerations in the same file, I got the error 'Unchecked' inside the main class.
You cannot put more than one public class in the same java file, except for inner classes.
If the relationship between them can be described as "BFSolver is a DFSolver", then you can use inheritance to get around the issue instead. Both of these classes would have to be in different files, since they're both public.
public class DFSolver {
protected boolean[][] didVisit;
protected List<Pair> expanded;
public DFSolver() {
// impl
}
// further impl
}
public class BFSolver extends DFSolver {
public BFSolver() {
// impl
}
}
The advantage here is that you don't have to copy or rewrite code to BFSolver; with the protected visibility modifier, you can access those fields just the same.
As others have stated, Java requires that only one public class can be in a single source file (unless the other is a static inner class), and the file name needs to match the class name. Other languages like Scala relax this requirement.
More interesting though is why you feel you want to. It looks instead like you either want to combine the classes into a single inheritance tree (though they have to still be different files) because they share behavior or combine common code into a utility class that both classes can delegate to.
But in any event, you're stuck with two files if you have two public non-static classes.

How to create a method in a Java class that is accesible from only one other class

I was wondering if anyone had a pattern that would help me achieve the following:
We have a JPA entity called Employee and on it there is a setLineManager method. We also have a separate updateLineStructureService, which is a Spring-managed service bean. We want to try and ensure that this setLineManager method can only be called from updateLineStructureService and not directly from any other class.
Is there a way to allow the service access to this method without exposing it to any other classes? I am aware that I could give the method package level access and put the service in the same package as Employee, but that will not fit our package structure so I would prefer not to do that. I am also aware that I could make the method private and just access it through reflection in this one place, but I do not like that solution at all.
Any ideas?
You can inspect the stacktrace (using Throwable#getStackTrace()) and see if it contains the allowed method on specified position.
In the following code snippet, System.PrivateEmployee is not visible outside the System class. Thus effectively privateMethod is private and can only be called from within the System class. Since System.PrivateEmployee extends System.PublicEmployee it can be used outside the System class as System.PublicEmployee
public class System
{
public static interface PublicEmployee { void publicMethod ( ) ; }
private static interface PrivateEmployee extends PublicEmployee { void privateMethod ( ) ; }
}
Use an inner class only available to the other service class:
public class Employee
{
static {
LineStructureService.registerEmployeeHelper(new EmployeeHelper() {
#Override
public void setLineManager(Employee emp, Object foo) {
emp.setLineManager(foo);
}
});
}
public static void init() {}
private void setLineManager(Object foo) { }
}
public class LineStructureService
{
private static volatile EmployeeHelper _helper;
static {
// ensure that Employee class is loaded and helper registered
Employee.init();
}
public static synchronized void registerEmployeeHelper(EmployeeHelper helper) {
_helper = helper;
}
public void doSomething(Employee emp)
{
// now this class can call setLineManager on Employee
_helper.setLineManager(emp, blah);
}
public interface EmployeeHelper {
public void setLineManager(Employee emp, Object foo);
}
}
The only way that a class can access private methods of other classes is with inner classes. If that is not an option, this can't be done.
One approach is to make two forms of Employee.
"BasicEmployee" has all the methods except setLineManager(). "ExtendedEmployee" extends BasicEmployee and adds a public void setLineManager(). (I'm assuming these are classes, but they could also be interfaces instead) Underneath the hood, everything is really a FullEmployee (for clarity, you could make BasicEmployee abstract). But, in the code, in all the classes except UpdateLineStructureService, you declare it as a BasicEmployee. Only in UpdateLineStructureService is it declared as a FullEmployee. So, only UpdateLineStructureService has easy access to setLineManager()
Now, a rogue coder could always cast their BasicEmployee to an ExtendedEmployee to access setLineManager(), so this isn't totally secure. But it's a reasonable pattern to limit access.
You could use AOP (e.g. AspectJ or CDI) to intercept the call to setLineManager(); if the caller is updateLineStructureService() call the method; if not do nothing, or raise an exception or whatever.

Java - Statements / Conversions | Pulpcore

[please note this may require AS3 + Java knowledge]
Background Information:
I'm trying to build a game using Java + Pulpcore, but I'm fairly new to the scene. The game I'm building could possibly be more performance intensive than I thought, and I know Java would solve my problems with this, but there are a couple questions I have dealing with strict-types, etc.
Here is my code in AS3:
Main.as3
import org.tbmb.champions.Container;
import org.tbmb.zombies.ZContainer;
public class Main extends MovieClip {
// ******* temporary properties ******* /
private var blunder:Container = null;
// ******* ******* /
public function Main() {
init(); // initialize objects
}
public function init():void {
blunder = new Container(Blunder as Class);
} // end of class
}
Container.as3
package org.tbmb.champions {
import flash.display.MovieClip;
public class Container extends MovieClip {
public function Container(champ:*) {
} // end of constructor
} // end of class
} // end of package
Blunder.as3
package org.tbmb.champions.blunder {
import flash.display.MovieClip;
public class Blunder extends MovieClip {
public function Blunder() {
} // end of constructor
} // end of class
} // end of constructor
1.) How would I rewrite in Java?
blunder = new Container(Blunder as Class);
2.) How would I be able to accept any Classes in Java for the above line within my Container class?
public function Container(champ:*) {
I need to do this because I'm sending different champion classes (depending on what the user picks) to a containing class that will hold all their other classes (health, etc). I need my Container class to accept any Class rather than just one; what type would I use?
Here is what I have in Java so far:
ZomboPulp.java (Main Class)
import pulpcore.scene.Scene2D;
import org.tnpfk.champions.Container;
import org.tnpfk.champions.blunder.Blunder;
import pulpcore.sprite.FilledSprite;
import pulpcore.image.Colors;
public class ZomboPulp extends Scene2D {
FilledSprite background = new FilledSprite(Colors.WHITE);
Container container = null; // Container that contain's blunder,
// and all his objects (health, mana, etc)
public void load() {
this.initScreen(); // initialize main screen.
this.initObjects(); // initialize our objects.
} // end of load();
public void initScreen() {
add(background);
} // end of initScreen();
public void initObjects() {
container = new Container(Blunder as Class); // ERROR HERE
} // end of initObjects();
}
Container.java
package org.tnpfk.champions;
public class Container {
public Container(Object champ) {
} // end of constructor
} // end of class
Sorry for the lengthy post, and thanks for any help. By the way, I did check StackOverflow; and Google, but I was unable to find anything about this.
Thanks,
jvmpulp
Alrighty! I have no experience with PulpCore, but I do know both AS3 and Java, so I think I can answer your question. First off, I guess I don't 100% understand what you need to do with the champ object in the Container class, and I really don't understand why you were doing Blunder as Class instead of just passing an instance of Blunder. Either way, here's what I'd recommend with what you have as of now:
public void initObjects() {
container = new Container(Blunder.class);
}
As you can see, you can get a Class instance just by getting the class property of any class. Now, you have the right idea with using Object as the type for the Container constructor for any type. However, using Object is bad practice (use method overloading/more specific types instead), and it's not even required here. Getting the class property will always be of type Class, even though they represent different classes. So, rewrite the constructor as this:
public Container(Class champ) {
}
Then, do whatever you need to do with the class.
Now, that's basically a direct port, but it seems some of the things you're doing are bad practice. The whole system of passing a Class object seems irrelevant and unnecessary; why not just pass an instance of the object? For example, like so:
public class Container {
protected Champion champ;
public Container(Champion champ) {
this.champ = champ;
}
}
Now, make Champion an abstract class that contains the common methods for all the champions:
public abstract class Champion {
protected Something something;
abstract Something getSomething();
}
(Obviously, the variable/method shown here are just examples.) Then, have your individual Champion classes subclass Champion:
public class Blunder extends Champion {
public Something getSomething() {
return this.something;
}
}
Etc. Then, finally, do this:
public void initObjects() {
container = new Container(new Blunder());
}
Obviously, this is a basic example, and you don't have to take my advice. But it would probably be easier to do than the system you already had in AS3.

Categories

Resources