Как правильно реализовать callback в java?
Вам поможет шаблон проектирования observer - https://ru.m.wikipedia.org/wiki/Наблюдатель_(шабло...
Смотрите реализацию на java.
Callback надо реализовать в виде отдельного интерфейса и сказать, что наше активити реализует этот интерфейс. В результате мы в DoRequestInterface просто передаем ссылку на нашу активити. А в активити реализуем нужные два метода для Callback. Во избежание утечек, рекомендую callback оборачивать в мягкую ссылку. interface DoRequestInterface {
    void execute(String url, DoRequesCallback callback);
}

interface DoRequesCallback {
    void successReq(JSONObject response);
    void errorReq(VolleyError error);
}

public abstract class DoRequestClass implements DoRequestInterface {
	@Override
  public void execute(String url, DoRequesCallback callback) {
      RequestQueue queue = Volley.newRequestQueue(context);
			final WeakReference<DoRequesCallback> weakCallback = new WeakReference<DoRequesCallback>(callback);
      JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
          @Override
          public void onResponse(JSONObject response) {
							DoRequesCallback callback = weakCallback.get();
							if (callback != null) {
              	callback.successReq(response);
							}
          }
      }, new Response.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError error) {
						DoRequesCallback callback = weakCallback.get();
						if (callback != null) {
            	callback.errorReq(error);
						}
          }

      });
      queue.add(jsObjRequest);
  }
}

public class MainActivity extends AppCompatActivity implements DoRequesCallback {
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		sendButton.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
          	DoRequestClass doRequestClass = new DoRequestClass();
	          doRequestClass.execute("http://myserver.local", this);
		      }
		  });
	}

	@Override
	public void successReq(JSONObject response){
	    txtDisplay.setText("Response => "+response.toString());
	}

	@Override
	public void errorReq(VolleyError error){
	    txtDisplay.setText("Error => "+error.toString());
	}
}