ive been learning java just a few weeks so my question might sound strange to you but i hope if someone could help . thanks.
so lets assume i have following as a class which have a property (colour) as private member of class so i can control the entry :
public class Shape{
private String colour;
public Shape(){
this.colour = "";
}
public Shape(String colour){
this.colour = colour;
}
public String getcolour(){
return this.colour;
}
public void setcolour(String colour){
this.colour = colour;
}
@Override
public String toString(){
return String.format("Shape = colour is %s ",this.colour);
}
}
and i have my constructor that value can be set in here, in main method:
public class xxx{
public static void main(string[],args){
Shape s = new Shape ("white");
System.out.format(" %s\n", s);
}
}
So can anyone help me with controlling the value that can be set as colour? For example I want if the entry was white it doesnt accept the value and want user to enter any colour but white ? Thanks
CodePudding user response:
There are a lot of ways to do this. One of my favorite aspects of programming is being able to do so many things in so many different ways. That being said, some ways are more right than others. Let's look at a few of the ways this can be done.
Validation
public Shape(String colour){
if ("white".equals(colour)) {
throw new InstantiationException("colour cannot be White");
}
this.colour = colour;
}
ENUM
public Shape(Colour color){
this.colour = colour;
}
public enum Colour {
BLUE,
BLACK,
BROWN
}
Now you can create a new Shape with new Shape(Colour.BLACK)
, but new Shape(Colour.WHITE)
won't work because white isn't in the enum. This is even better in that it is checked at compile time instead of runtime.
Inheritance
public interface Shape {
String getColour();
}
public class BlackShape implements Shape {
private String colour = "Black";
@Override
public void getColour() {
return colour;
}
}
Now, you can create a new Shape:
Shape shape = new BlackShape();
System.out.println(shape.getColour);
Combined
In this version, we create an Enum called color to hold the valid colours you want to have available.
public interface Shape {
String getColour();
}
public class BlackShape implements Shape {
private Colour colour = Colour.BLACK;
@Override
public void getColour() {
return colour;
}
}
CodePudding user response:
You can actually make a method with validation before creating Shape object like:
public class xxx{
public static void main(string[],args){
String color = "white";
validateColor(color);
Shape s = new Shape (color);
System.out.format(" %s\n", s);
}
}
private static void validateColor(String color) {
if (Objects.equals("white", color)) {
throw new IllegalArgumentException("Color must not be white");
}
}
Or if you want to control this at the class level you can do validation like that in the constructor, but imo it is worse practice. It would looks something like:
public class Shape{
private String colour;
public Shape(){
this.colour = "";
}
public Shape(String colour){
validateColor(colour)
this.colour = colour;
}
public String getcolour(){
return this.colour;
}
public void setcolour(String colour){
this.colour = colour;
}
@Override
public String toString(){
return String.format("Shape = colour is %s ",this.colour);
}
private void validateColor(String color) {
if (Objects.equals("white", color)) {
throw new IllegalArgumentException("Color must not be white");
}
}
}
Also remember that your class is mutable it means that you can change the properties (using for example method setcolour(String colour) that should be also be validated).
More readable would be create new class for example ShapeValidator (or something like that, which would be responsible for validating data).
Idea also about changing the coding style (in java camelCase is used for methods and variables and UpperCamelCase for classes)
CodePudding user response:
A type-safe way to do this is use Enums.
Create a new enum that represents the colors you want to use:
public enum Colour {
WHITE("white"),
RED("red"),
GREEN("green"),
BLUE("blue"),
BLACK("black");
private final String value;
Color(String value) {
this.value = value)
}
public String getValue() {
return this.value;
}
}
Then update your code to use the above Enum instead of a String value.
public class Shape{
private Color colour;
public Shape(){
this.colour = Color.WHITE;
}
public Shape(Colour colour){
this.colour = colour;
}
public Colour getcolour(){
return this.colour;
}
public void setColour(Colour colour){
this.colour = colour;
}
@Override
public String toString(){
return String.format("Shape = colour is %s ", this.colour.getValue());
}
}
Drawbacks
This code isn't very extensible. Meaning if you want to add new colors in the future, you'll have to edit the Color Enum above and add them.