This is the code snippet
public class Square{
private double length;
private double width;
public Square(double a, double b){
length = a;
width = b;
}
public static void main(String args[]){
Square box = new box(3.0,5.0);
}
}
Here is my question, what is the difference between Square box = new box(3.0,5.0); and Square box = new Square(3.0,5.0);
the new box(3.0,5.0) suppose is to be call the box constructor which I don't have. but it will call Square constructor as well. It really confuse me why written in this way also is correct
The difference is new Square(3.0, 5.0) is valid but new box(3.0, 5.0) is a compile error. If it's actually compiling for you then your project must also include another class called box (perhaps in another file) which you haven't included in your post.
Related
Here's a bare minimum pseodo-code of what I use:
class A{
//other variables
B b;
void delayedPartnerInit(B b){
this.b=b;
}
}
class B{
//some other variables
A a;
void delayedPartnerInit(A a){
this.a=a;
}
}
I could make it into a single class but certain members(not shown here) of A are needed to exist before data about B. In other words, objects of A and B are instanced at different times but need reference of each other's variables once both set of variables are available.
The question is there a better way to do this? Am I missing some basic concept of programming?
Though I am currently working on C#, I have had this thought many times before when working with other languages too.
Update: I am using this in Unity game engine where B is Unity C# script. Since Unity doesn't allow us create scripts without adding it to something I need 2 classes. I get certain data(A's data) earliar which needs processing.
Didn't mention this earlier because I asked it as a generic question.
Note before closing as duplicate: I checked similar questions but found only specific questions that caused issues to authors who tried to do what I am doing. My question is whether it is a bad practice.
Tightly coupled classes are generally bad practice:
Changes in one class lead to changes in another.
You cannot test one of classes without creating (or mocking) another one. Which in your case creates circular dependency.
Both classes depend on each other's implementations, not abstractions.
Harder for other persons (or yourself half a year later) to understand and reason about first class logic without inspecting second class as well.
Since Unity doesn't allow us create scripts without adding it to something I need 2 classes. I get certain data(A's data) earliar which needs processing
MVC pattern for Unity provides useful trick for decoupling monobehaviours:
interface ISomeObjectView {
event Action OnUpdate;
event Action Destroyed;
event Action TriggerEntered;
void SetTransform(Vector3 position, Quaternion rotation);
void AddForce(Vector3 force);
// Other methods or events you need to expose:
// MouseOver, OnFixedUpdate, Move() or SetScale(), ...
}
MonoBehaviour itself does not contain any logic, it simply invokes events and uses incoming values:
public void SetTransform(Vector3 position, Quaternion rotation)
{
// Params validation
transform.rotation = rotation;
transform.position = position;
}
private void Update()
=> OnUpdate?.Invoke();
MonoBehaviour logic must be moved to your data class or new controller class. Now your data class simply links itself to provided interface events and methods without circular dependencies. Monobehaviour does not require any references to other classes, it simply provides methods to manipulate itself and events to catch input.
This trick helps in several ways:
MonoBehaviour doesn't depend on anything and doesn't require any references to other classes.
Your data/logic classes doesn't require ant special knowledge about monobehaviours, only provided interface.
You can have several implementations for interface, switching different views depending on situation.
Easy to test, easy to mock.
You can move all the "Unity stuff" inside MonoBehaviour and write all related classes on pure C#. If you want to.
Please note that using event Action is not conventional way to deal with events! I think it's very convenient, but I'd suggest to use conventional EventHandler (UnityEvents is another option that might suit your needs).
Update: an example of simple MVC.
Consider the following Player controller:
[Serializable]
public class PlayerInfo {
// Values configurable via inspector
[SerializeField] private float speed = 1.5f;
[SerializeField] private float jumpHeight = 5;
[SerializeField] private float damage = 15;
[SerializeField] private Player playerPrefab;
public float Speed => speed;
public float JumpHeight => jumpHeight ;
public float Damage => damage;
private Player playerInstance;
public void InitializePlayer() {
playerInstance = Instantiate(playerPrefab);
playerInstance.Info = this;
}
public void TeleportTo(Vector3 newPosition) {
playerInstance.transform.position = newPosition;
}
}
public class Player : MonoBehaviour {
public PlayerInfo Info { get; set; }
private Rigidbody rb;
private void Awake() {
rb = GetComponent<Rigidbody>();
}
private void Update() {
if (Input.GetButtonDown("Jump")
rb.AddForce(Vector3.up * info.JumpHeight);
Vector3 movement = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
rb.AddForce(movement * info.Speed);
}
private void OnTriggerEnter(Collider other) {
var enemy = other.GetComponent<Enemy>();
if (enemy != null)
enemy.TakeHit(info.Damage);
}
}
There you go. PlayerInfo is created before Player. PlayerInfo references Player and Player references PlayerInfo. Player is used to move gameobject and attack enemies, PlayerInfo contains required info. What can we do here?
First, Rewrite MonoBehaviour without any logic:
public class PlayerView : MonoBehaviour {
private Rigidbody rb;
// Events for future subscription.
public event Action OnUpdate;
public event TriggerEntered<Collider>;
// Simple initialization of required components.
private void Awake() {
rb = GetComponent<Rigidbody>();
}
// Unity methods doing nothing but invoking events.
private void Update() {
OnUpdate?.Invoke();
}
private void OnTriggerEnter(Collider other) {
TriggerEntered?.Invoke(other);
}
// We still need a method to move our player, right?
public void Move(Vector3 direction) {
rb.AddForce(direction);
}
public void SetPosition(Vector3 position) {
transform.position = position;
}
}
Now you need class containing data about player:
[Serializable]
public class PlayerModel {
[SerializeField] private float speed = 1.5f;
[SerializeField] private float jumpHeight = 5;
[SerializeField] private float damage = 15;
public float Speed => speed;
public float JumpHeight => jumpHeight ;
public float Damage => damage;
}
Now we need a way to tie those two together:
public class PlayerController {
private readonly PlayerModel model;
private readonly PlayerView view;
public PlayerController(PlayerModel model, PlayerView view) {
// Validate values here.
this.model = model;
this.view = view;
// Linking logic to events.
view.OnUpdate += Move;
view.TriggerEntered += Attack;
}
// Actual logic moved here.
private void Move() {
Vector3 movement = Vector3.zero;
if (Input.GetButtonDown("Jump")
movement += Vector3.up * model.JumpHeight;
movement += new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")) * model.Speed;
view.Move(movement);
}
private void Attack(Collider other) {
var enemy = other.GetComponent<Enemy>();
if (enemy != null)
enemy.TakeHit(model.Damage);
}
// Method from PlayerInfo to set player position without actual movements.
public void MoveTo(Vector3 position) {
view.SetPosition(position);
}
}
Now you have 3 classes instead of 2, but model and view classes are very simple and do not require any dependencies. All the work is done by Controller class, which receives other two pieces and ties them together.
It becomes even better when interfaces are introduced in addition to classes: IPlayerModel, IPlayerView, IPlayerController.
You might think that it would be easier to create single class instead of three linked classes, but in the long run you will thank yourself for using this pattern: view and model are extremely simple, easy to read, easy to check for errors, easy to expand with new functionality. Single class, on the other hand, will quickly grow to hundreds of lines and become a nightmare to test and expand.
I strongly recommend this article with more complicated examples of MVC.
This code seems to match pretty close to an example I found on online, but its not right, and I can't find an example that matches what I'm trying to do. Maybe I just don't have the parameters and fields setup correctly; or maybe my approach is wrong.
package vibrationSimulator;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import sineWaveAnimation.SineDisplay;
import audioOutput.JFrame_sliderSine;
public class VibrationSimulator {
private static List<MachineParameters> machineParameterArray;
private static int ia;
private static MachineParameters machineParameter_1;
public static void main(String[] args) {
Start();
}
public static void Start() {
ArrayList<MachineParameters> machineParameterArray = new ArrayList<MachineParameters>();
MachineParameters machineParameter_1 = new MachineParameters();
machineParameter_1.frame.setVisible(true);
}
public static void Process() {
// machineParameterArray.add(machineParameter_1);
if (MachineParameters.isGoDone()) {
// machineParameterArray[ia] = machineParameter_1;
MachineParameters machineParameter_1 = new MachineParameters();
machineParameter_1.frame.setVisible(true);
} else {
StartAnimations();
}
}
I have MachineParameters Class whith a simple GUI for inputting the values. Start creates the first instance of MachineParameters and Process is supposed to add that instance to the ArrayList when it is called from the MachineParameter Class. Process creates another instance if GoDone is true or starts and animation if false. The ArrayList will be used to set the parameters for the animation. The true/false is set by the Submit or Done buttons on the GUI.
When I add the Remmed out line:
// machineParameterArray.add(machineParameter_1);
machineParameters_1 doesn't refer to the instance.
Also, all instances have the same name; I'm not sure how to increment a variable name - doesn't seem correct.
Laugh at me if you want, but I will get this right eventually; and then I'll know how to do it.
Remove ArrayList from the constructor. Apparently it creates a local variable instead of an instance.
So:
machineParameterArray = new ArrayList();
I am making a maze that the player has to navigate with the mouse, but they lose when the hit a wall. I want to make sure the player has the mouse in the right place to start, so I am trying to switch to the game state once the mouse intersects with a square indicator on screen.
In the tutorial I was learning from, they did this:
public static class Point extends AbstractEntity {
public Point(double x, double y, double width, double height) {
super(x, y, width, height);
}
#Override
public void draw() {
glBegin(GL_POINTS);
glVertex2d(x, y);
}
#Override
public void update(int delta) {
// Blank
}
}
Point.setLocation(Mouse.getX(), 480 - Mouse.getY() - 1);
if(Maze1.intersects(Point)){
System.out.println("You would have lost");
}
I tried to do this:
case MAZE:
if(Maze1.intersects (Point) ){
state = State.GAMEOVER;
}
break;
I get the error, "Point cannot be resolved to a variable". Please help.
It looks like when you call Maze1.intersects you are passing the actual Point class rather than an instance of that class. This is why you get the "Point cannot be resolved to a variable" error. You need to create an instance of Point, call setLocation on that instance and then pass that into Maze1.intersects.
For your example to work I would either remove the argument on Maze1.intersects and have it access the Point class directly or change Point to it's no longer static, declare an instance of Point and pass that instance into Maze1.intersect.
Declaring the Point class as static does not mean you can pass the class into method, etc, like a regular variable as it's simply a way of sharing data and behaviour. Also, keep in mind that by declaring Point as static you are saying that there will only ever be one Point.
I would maybe consider dropping the static keyword and creating an instance of Point classed "startingPoint". You can then pass this into Maze1.intersects. Then if you need to determine if the player intersects with other "points" in the maze, then you can create other instances to represent those points.
I am trying to write a simple program that has two classes. I want one class (with the main method) to handle all the input and output and the other class to handle all of the mathematics then return the calculations to the main method. I can successfully pass variables from main method to an object in the mathematics class and have tested the results in that method with a println but can't seem to pass the finished calculations back to my main method. Here is my code, please help me understand. Thank you very much
Here is class with main method
import java.util.Scanner;
public class io {
public static void main (String[] args){
Scanner chargeTankStartGaugeFeetInput = new Scanner(System.in);
Scanner chargeTankStartGaugeInchesInput = new Scanner(System.in);
System.out.println("What is the charge tank's start gauge feet: ");
String chargeTankStartGaugeFeet = chargeTankStartGaugeFeetInput.nextLine();
System.out.println("What is the charge tank's start gauge inches: ");
String chargeTankStartGaugeInches = chargeTankStartGaugeInchesInput.nextLine();
math mathObject = new math();
mathObject.changeGaugesToInches(chargeTankStartGaugeFeet,
chargeTankStartGaugeInches);
System.out.println(mathObject.totalInches(totalInches)
+ " is total inches in io");
}
}
I get an error that says "totalInches" in the main method cannot be resolved to a variable. Is my thinking even close as to how this is supposed to work?
And here is the math class
public class math {
public void changeGaugesToInches(String arg1, String arg2) {
double arg1Double = Double.valueOf(arg1).doubleValue();
double arg2Double = Double.valueOf(arg2).doubleValue();
double totalInches = arg1Double * 12 + arg2Double;
System.out.println(totalInches + " is the total inches");
}
}
You can return the value from the method...
public double changeGaugesToInches(...)
{
....
return totalIncehs;
}
Firstly, by convention, all class and enum names in java should begin with a capital letter. Secondly, you may want to use a more descriptive name for your math class, "UnitsConverter" if that is all that it does.
In changeGaugesToInches, you should rename arg1 and arg2 to feet and inches.
Most importantly, you need to change the method to return the result, and assign it to a variable in your main method:
double totalInches = mathObject.changeGaugesToInches(chargeTankStartGaugeFeet, chargeTankStartGaugeInches);
public double changeGaugesToInches(String arg1, String arg2){
//...
return totalInches;
}
Because this method does not use any instance variables, unless you think you might over ride this method in a subclass (to add metric units, for example) the code would be more efficient if you declared it as static. Also, you can probably use integers unless you require more accuracy.
double totalInches = UnitsConverter.changeGaugesToInches(chargeTankStartGaugeFeet, chargeTankStartGaugeInches);
public static int changeGaugesToInches(String feet, String inches){
return changeGaugesToInches( Integer.parseInt(feet), Integer.parseInt(inches) );
}
// this method can be used more efficiently from parts of your app that already have the units as integers.
public static int changeGaugesToInches(int feet, int in
//...
return totalInches;
}
Any void method can't have return value. Since,
public void changeGaugesToInches(String arg1, String arg2) is a void method therefore it has no return type.
If you make it static then you can't use math mathObject = new math();
I'm a little new to AS3, but I have a question.
I have a variable called "lives". It is a Number. I also have a class. It is called "Enemy". Within the "Enemy" class, there is a function called "collision_detection". How can I change the value of "lives" from "collision_detection"? Thank you!
EDIT:
I have an Enemy class. I need to communicate from within the class to let the main program know that a collision occurred. How can I send this message to the main program?
EDIT II:
Here is the collision function :
public class Enemy extends MovieClip {
private var hoster : MovieClip;
private var life: Number;
public function temp_bad_thing(host : MovieClip , lives : Number) {
this.addEventListener(Event.ENTER_FRAME , check_collision);
hoster = host;
life = lives;
this.y = 0;
this.x = Math.floor(Math.random()*(551));
}
private function check_collision (evt:Event) : void{
if(this.hitTestObject(hoster) == true){
trace('COLLISION');
parent.removeChild(this);
removeEventListener(Event.ENTER_FRAME , check_collision);
}
}
}
Now how can I get this class to change the value of a variable in my main flash file?
If the variable is declared in the same package and not in another class you should be able to assign to it without doing anything special.
If it's in another class then declare the lives variable as static public var lives: Number. This way you can assign to the variable using otherClass.lives. Only one copy of static variable will exist regardless of how many objects you make.