I'm building an android app (but this is not important for the post) and I'm writing a method called scrollUntilSelectedAvatar() that contain a class:
public class AvatarManager {
private HorizontalScrollView avatarPageHorizontalScrollView;
//mehod that contains the inner class
public void scrollUntilSelectedAvatar(HorizontalScrollView avatarPageHorizontalScrollView){
this.avatarPageHorizontalScrollView = avatarPageHorizontalScrollView;
avatarPageHorizontalScrollView.post(new Runnable() {
#Override
public void run() {
AvatarManager.this.avatarPageHorizontalScrollView.scrollTo(100, 0);
}
});
}
}
My question is: what's the correct way to access avatarPageHorizontalScrollView (that I pass to the method as an argument) inside the inner class new Runnable().
The way I found (AvatarManager.this.avatarPageHorizontalScrollView) doesn't seems the best way.
Thank everybody for the help :)
The way you did it - is the one and only correct. Syntax of some thing about inner classes may seem quite strange. But it is just like it is.
public class A {
private int a;
private abstract class B {
public abstract void printA();
}
public B makeB() {
return new B() {
#Override
public void printA() {
System.out.println(A.this.a);
}
};
}
}
Related
Sorry for the very noob question I'm new to this
For example let say I have this code:
public class Amazing {
public static void DoSomethingAmazing() {
System.out.println("I did something amazing");
}
}
public class MainClass {
public static void main(String[] args) {
Amazing.DoSomethingAmazing();
}
}
Would it be possible for me to make so whenever Amazing.DoSomethingAmazing() is used it does something else (For example prints "I did not do something amazing" instead) without changing either the class the method is in or the class using it?
Closest you can get to this is by extending Amazing class and overriding DoSomethingAmazing method, e.g.:
public class Amazing {
public void DoSomethingAmazing() {
System.out.println("I did something amazing");
}
}
public class SomethingMoreAmazing extends Amazing {
public void DoSomethingAmazing() {
System.out.println("I did something more amazing");
}
}
In the main method, you can do this:
Amazing a = new SomethingMoreAmazing();
a.DoSomethingAmazing();
It will print I did something more amazing i.e. it will make DoSomethingAmazing do something else without changing it.
You can read more about method overriding here.
I am writing a testing framework using Gauge.
I want some initilization logic performed in one class, and the steps logic to reuse it, like this:
public class A {
protected String property = "";
#BeforeSpec
public void init(){
property = "hello";
}
}
public class B extends A {
#Step("...")
public void verifyProperty() {
assertEquals(property, "hello");
}
}
I can't seem to be able to achieve this. When performing the steps, the "property" is always null.
Placing the #BeforeSpec in class B and calling super.init() works, but I would like to avoid having this call in every test class that extends A.
Has anyone encountered and solved such an issue?
Try to use a static variable:
public class A {
public static String property = "";
#BeforeSpec
public void init(){
property = "hello";
}
}
public class B {
#Step("...")
public void verifyProperty() {
assertEquals(A.property, "hello");
}
}
I have two classes and one interface.
Interface:
public interface MyBirthdayEvent {
void itsMyBirthday();
}
First class:
public class MyBirthdayButton
{
public void addOnClickedListener(MyBirthdayEvent mbe){}
}
Second class:
public class MyBirthday {
private MyBirthdayButton myBirthdayButton = new MyBirthdayButton();
MyBirthday() {
myBirthdayButton.addOnClickedListener(new MyBirthdayEvent() {
public void itsMyBirthday() {
System.out.println("Happy Birthday");
}
});
}
}
Then in main, I have this:
public class TestThisStuff {
public static void main(String[] args) {
MyBirthday myBirthday = new MyBirthday();
}
}
As can be seen from the code, I am using an anonymous class in the MyBirthday constructor. In doing so, I am trying to get the string "Happy Birthday" to print to the console.
My problem is, when I call the MyBirthday constructor in main by making a new myBirthday object, I am not seeing the string "Happy Birthday" print to the console. Shouldn't it print to the console? If not, what I am doing wrong?
What you can do is this:
public interface MyBirthdayEvent {
void itsMyBirthday();
default void invoke() {
itsMyBirthday();
}
}
...
public class MyBirthdayButton
{
public void addOnClickedListener(MyBirthdayEvent mbe){
mbe.invoke();
}
}
...
Also, it will work without it, but use a lambda rather than an anonymous inner class. This looks much better.
MyBirthday() {
myBirthdayButton.addOnClickedListener(() ->
System.out.println("Happy Birthday"));
}
you can move System.out.println("some words")statement to your MyBirthdayEventconstructor
it didn't show in your console because you haven't invoke the method
I have understood the fragile Base class problem, and I know that we can solve it using Composition over Inheritance or declaring private method in the superclass.
Now I'm trying to understand how to solve this problem using helper method, so I will put the classic code of fragile base class and then I will put my solution with helper method, tell me if I do something wrong please.
This is the code of a fragile base class (from wikipedia)
public class JavaApplicationProvaHello {
public class A {
private int i;
public void inc1(){
i++;
}
public void inc2(){
inc1();
}
}
//---------------------------
public class B extends A{
#Override
public void inc1(){
inc2();
}
}
//------------------------
public class Test{
public static void main(String[] args) {
B b = new B();
b.inc1();
}
}
}
Now I change the class A and put two private helper methods which will be called by the public method inc1 and inc2
public class A {
protected int i;
public void inc1(){
inc1Helper();
}
public void inc2(){
inc2Helper();
}
private void inc1Helper(){
i++;
}
private void inc2Helper(){
inc1Helper();
}
}
In my compiler everything works, I was asking myself if this is the best solution to solve fragile base class with helper methods. Thank you for the attention.
"Best" is an opinion.
In my opinion, a better answer would be to leave a Javadoc comment on inc2() stating that it calls inc1().
/** Increments <code>i</code> by calling <code>inc1()</code> */
public void inc2()
...
Then anyone who extends A can see that in the documentation. If they miss it, then they will know when they look at the stack trace for their stack overflow exception.
This way still requires a few lines in the file but requires no more actual lines of functional logic code and no more generated byte code. The very Wikipedia article you mention suggests (and for Java, nonetheless) documentation as one of the answers.
I have FinanceRequests and CommisionTransactions in my domain.
If I have a list of FinanceRequests each FinanceRequest could contain multiple CommisionTransactions that need to be clawed back. Dont worry how exactly that is done.
The class below (very bottom) makes me feel all fuzzy and warm since its succint and reuses existing code nicely. One problem Type erasure.
public void clawBack(Collection<FinanceRequest> financeRequestList)
public void clawBack(Collection<CommissionTrns> commissionTrnsList)
They both have the same signature after erasure, ie:
Collection<FinanceRequest> --> Collection<Object>
Collection<CommissionTrns> --> Collection<Object>
So eclipse complainst that:
Method clawBack(Collection) has the same erasure clawBack(Collection) as another method in type CommissionFacade
Any suggestions to restructure this so that it still an elegant solution that makes good code reuse?
public class CommissionFacade
{
/********FINANCE REQUESTS****************/
public void clawBack(FinanceRequest financeRequest)
{
Collection<CommissionTrns> commTrnsList = financeRequest.getCommissionTrnsList();
this.clawBack(commTrnsList);
}
public void clawBack(Collection<FinanceRequest> financeRequestList)
{
for(FinanceRequest finReq : financeRequestList)
{
this.clawBack(finReq);
}
}
/********COMMISSION TRANSACTIOS****************/
public void clawBack(CommissionTrns commissionTrns)
{
//Do clawback for single CommissionTrns
}
public void clawBack(Collection<CommissionTrns> commissionTrnsList)
{
for(CommissionTrns commTrn : commissionTrnsList)
{
this.clawBack(commTrn);
}
}
}
Either rename the methods, or use polymorphism: use an interface, and then either put the clawback code in the objects themselves, or use double-dispatch (depending on your design paradigm and taste).
With code in objects that would be:
public interface Clawbackable{
void clawBack()
}
public class CommissionFacade
{
public <T extends Clawbackable> void clawBack(Collection<T> objects)
{
for(T object: objects)
{
object.clawBack();
}
}
}
public class CommissionTrns implements Clawbackable {
public void clawback(){
// do clawback for commissions
}
}
public class FinanceRequest implements Clawbackable {
public void clawBack(){
// do clwaback for FinanceRequest
}
}
I prefer this approach, since I'm of the belief your domain should contain your logic; but I'm not fully aware of your exact wishes, so I'll leave it up to you.
With a double dispatch, you would pass the "ClawbackHandler" to the clawback method, and on the handler call the appropriate method depending on the type.
I think your best option is to simply name the method differently.
public void clawBackFinReqs(Collection<FinanceRequest> financeRequestList) {
}
public void clawBackComTrans(Collection<CommissionTrns> commissionTrnsList) {
}
In fact, it's not too bad, since you don't get anything extra out of having the same name on them.
Keep in mind, that the JVM will not decide which method to call at runtime. As opposed to virtual methods / method overriding resolution of overloaded methods are done at compile time. The Java Tutorials on method overloading even points out that "Overloaded methods should be used sparingly...".
Here is a trick with overloading by the second varargs parameter for the CommissionFacade class from the question:
public class CommissionFacade {
public void clawBack(Collection<FinanceRequest> financeRequestList, FinanceRequestType ...ignore) {
// code
}
public void clawBack(Collection<CommissionTrns> commissionTrnsList, CommissionTrnsType ...ignore) {
// code
}
/*******TYPES TO TRICK TYPE ERASURE*******/
private static class FinanceRequestType {}
private static class CommissionTrnsType {}
}
The code snippet to fast-check this trick works:
import java.util.ArrayList;
class HelloType {
public static void main(String[] args) {
method(new ArrayList<Integer>());
method(new ArrayList<Double>());
}
static void method(ArrayList<Integer> ints, IntegerType ...ignore) {
System.out.println("Hello, Integer!");
}
static void method(ArrayList<Double> dbs, DoubleType ...ignore) {
System.out.println("Hello, Double!");
}
static class IntegerType {}
static class DoubleType {}
}