访问私有数组中对象的私有变量
Access to private variables of Objects that are within a private array
我想创建一个可以有多个菜单的 Restaurant 对象。每个菜单可以有多个类别,每个类别可以有多个项目。每件商品都有名称、价格和描述。
--Company--
-Menu ONE-
-Menu Name-
-Category ONE-
-Category Name-
-Menu Item ONE-
-Menu Item Name
-Menu Item Price
-Menu Item Description
-Menu Item TWO-
-Category TWO-
-Menu TWO-
示例 class没有构造函数、getters / setter 或方法。
拥有一系列菜单的公司
public class Company
{
// Class constants
// Class variables
private String companyName; // Stores company name
private String hours; // Restaurant hours
private String phoneNumber; // Restaurant phone number
private Menu[] menuList; // Array of menu objects
private int menuCount; // Number of menus in the array
}
包含类别数组的菜单
public class Menu
{
// Class constants
// Class variables
private String menuName; // Name of Menu
private Category[] categoryList; // Array of category objects
private int categoryCount; // Number of categories in the array
}
包含菜单项数组的类别
public class Category
{
// Class constants
// Class variables
private String categoryName; // Name of Menu
private MenuItem[] menItemList; // Array of MenuItem objects
private int menuItemCount; // Number of menu items in the array
}
具有名称、价格和描述的单行项目
public class MenuItem
{
// Class constants
// Class variables
private String name; // Name of Menu Item
private float price; // Price of the Menu Item
private String description; // Description of the Menu Item
}
在驱动程序 class 中,如果我只能访问公司的方法,我将如何更改菜单项中的任何内容?
我考虑过为每个私有项目数组设置一个 getter,但是向下挖掘 3 个级别进入私有数组似乎很难实现。它不像 Company.Menu.Category.MenuItem.editName(newName);
那么简单
注意* 我对 "Should use a Linked list or ArrayList" 答案不感兴趣。程序要求需要基本数组。
让我知道是否需要更清楚,或者您是否想要 SSCCE。
如果您为必须从外部读取的成员创建 getter 方法,则必须深入挖掘才能从 Menu 对象中获取所需的信息。这就是封装的意义所在。如果将重复这些操作,您可以创建一个助手 class / 方法来管理数组的各个级别。
.
的链接是避免它的不好的做法,您可以执行以下操作
在class公司
中创建方法modifyMenu
public class Company {
public modifyMenu (int menuIndexToModify, int categoryIndex, MenuItem itemWithModification){
menuList[menuIndexToModify].modifyMenuItem(categoryIndex, menuItemIndex, itemWithModification);
}
}
在 Menu
class
中创建方法 modifyMenuItem
public class Menu{
public void modifyMenuItem(int categoryIndex, int menuItemIndex, MenuItem itemWithModification){
categoryList[categoryIndex].modifyMenuItem(menuItemIndex,itemWithModification);
}
}
在 Class 中创建 modifyMenuItem
方法 Category
public class Category{
public void modifyMenuItem(int menuItemIndex, MenuItem itemWithModification){
menuItemList[menuItemIndex].modify(itemWithModification);
}
}
克里特方法 modify
MenuItem
public void modify( MenuItem itemWithModification){
this.name = itemWithModification.name
// assign other stes similarly
}
现在你只需要调用方法 modifyMenu
,将参数传递给它。
I thought about having a getter for each private array of items, but
digging down 3 levels into private arrays seems very difficult to
implement. It's not as simple as
Company.Menu.Category.MenuItem.editName(newName);
实现起来并不难,但是调用连续的 getter 是一种反模式,例如:
company.getMenu().getCategory().getMenuItem().editName(newName);
Demeter law 状态为:
Each unit should have only limited knowledge about other units: only
units "closely" related to the current unit.
Each unit should only talk to its friends; don't talk to strangers.
Only talk to your immediate friends.
因此,要解决您的问题,您将不得不重构您的设计,使您的对象相互协作。
Collaborating/Cascading接近
您可以定义一个 editItemName()
方法,该方法由层次结构中的每个对象依次调用。
Company
可以定义方法如:
public void editItemName(String menuName, String categoryName, String itemName, String newName){
Menu menu = findMenu(menuName);
menu.editItemName(category, item, newName);
}
Menu
可以定义方法如:
public void editItemName(String categoryName, String itemName, String newName){
Category category = findCategory(categoryName);
category.editItemName(item, newName);
}
Category
可以定义方法如:
public void editItemName(String itemName, String newName){
MenuItem item = findItem(itemName);
item.editItemName(newName);
}
最后MenuItem
可以定义如下方法:
public void editItemName(String newName){
this.name = newName;
}
更直接的方法(如果适用)
传递这么多参数对客户来说可能很麻烦。
作为替代方案,如果 Item
对象是唯一的(就 equals()
而言)并且您可以从客户端获取它,您可以使事情变得更简单。
您可能只需要将 MenuItem
(叶子)中的方法定义为:
public void editItemName(String newName){
this.name = newName;
}
您可以定义一个按标识符存储项目的地图:
Map<String, MenuItem> mapUniqueItems = new HashMap<>();
// add items in the map
mapUniqueItems.put("item1", new MenuItem(..));
mapUniqueItems.put("item2", new MenuItem(..));
// add items in the hierarchy as you actually do
...
稍后您可以根据其 ID 编辑项目,例如:
String itemIdentifier = ...;
MenuItem item = mapUniqueItems.get(itemIdentifier);
item.editItemName("new value");
我想创建一个可以有多个菜单的 Restaurant 对象。每个菜单可以有多个类别,每个类别可以有多个项目。每件商品都有名称、价格和描述。
--Company--
-Menu ONE-
-Menu Name-
-Category ONE-
-Category Name-
-Menu Item ONE-
-Menu Item Name
-Menu Item Price
-Menu Item Description
-Menu Item TWO-
-Category TWO-
-Menu TWO-
示例 class没有构造函数、getters / setter 或方法。
拥有一系列菜单的公司
public class Company
{
// Class constants
// Class variables
private String companyName; // Stores company name
private String hours; // Restaurant hours
private String phoneNumber; // Restaurant phone number
private Menu[] menuList; // Array of menu objects
private int menuCount; // Number of menus in the array
}
包含类别数组的菜单
public class Menu
{
// Class constants
// Class variables
private String menuName; // Name of Menu
private Category[] categoryList; // Array of category objects
private int categoryCount; // Number of categories in the array
}
包含菜单项数组的类别
public class Category
{
// Class constants
// Class variables
private String categoryName; // Name of Menu
private MenuItem[] menItemList; // Array of MenuItem objects
private int menuItemCount; // Number of menu items in the array
}
具有名称、价格和描述的单行项目
public class MenuItem
{
// Class constants
// Class variables
private String name; // Name of Menu Item
private float price; // Price of the Menu Item
private String description; // Description of the Menu Item
}
在驱动程序 class 中,如果我只能访问公司的方法,我将如何更改菜单项中的任何内容?
我考虑过为每个私有项目数组设置一个 getter,但是向下挖掘 3 个级别进入私有数组似乎很难实现。它不像 Company.Menu.Category.MenuItem.editName(newName);
那么简单注意* 我对 "Should use a Linked list or ArrayList" 答案不感兴趣。程序要求需要基本数组。
让我知道是否需要更清楚,或者您是否想要 SSCCE。
如果您为必须从外部读取的成员创建 getter 方法,则必须深入挖掘才能从 Menu 对象中获取所需的信息。这就是封装的意义所在。如果将重复这些操作,您可以创建一个助手 class / 方法来管理数组的各个级别。
.
的链接是避免它的不好的做法,您可以执行以下操作
在class公司
中创建方法modifyMenu
public class Company {
public modifyMenu (int menuIndexToModify, int categoryIndex, MenuItem itemWithModification){
menuList[menuIndexToModify].modifyMenuItem(categoryIndex, menuItemIndex, itemWithModification);
}
}
在 Menu
class
modifyMenuItem
public class Menu{
public void modifyMenuItem(int categoryIndex, int menuItemIndex, MenuItem itemWithModification){
categoryList[categoryIndex].modifyMenuItem(menuItemIndex,itemWithModification);
}
}
在 Class 中创建 modifyMenuItem
方法 Category
public class Category{
public void modifyMenuItem(int menuItemIndex, MenuItem itemWithModification){
menuItemList[menuItemIndex].modify(itemWithModification);
}
}
克里特方法 modify
MenuItem
public void modify( MenuItem itemWithModification){
this.name = itemWithModification.name
// assign other stes similarly
}
现在你只需要调用方法 modifyMenu
,将参数传递给它。
I thought about having a getter for each private array of items, but digging down 3 levels into private arrays seems very difficult to implement. It's not as simple as Company.Menu.Category.MenuItem.editName(newName);
实现起来并不难,但是调用连续的 getter 是一种反模式,例如:
company.getMenu().getCategory().getMenuItem().editName(newName);
Demeter law 状态为:
Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
Each unit should only talk to its friends; don't talk to strangers.
Only talk to your immediate friends.
因此,要解决您的问题,您将不得不重构您的设计,使您的对象相互协作。
Collaborating/Cascading接近
您可以定义一个 editItemName()
方法,该方法由层次结构中的每个对象依次调用。
Company
可以定义方法如:
public void editItemName(String menuName, String categoryName, String itemName, String newName){
Menu menu = findMenu(menuName);
menu.editItemName(category, item, newName);
}
Menu
可以定义方法如:
public void editItemName(String categoryName, String itemName, String newName){
Category category = findCategory(categoryName);
category.editItemName(item, newName);
}
Category
可以定义方法如:
public void editItemName(String itemName, String newName){
MenuItem item = findItem(itemName);
item.editItemName(newName);
}
最后MenuItem
可以定义如下方法:
public void editItemName(String newName){
this.name = newName;
}
更直接的方法(如果适用)
传递这么多参数对客户来说可能很麻烦。
作为替代方案,如果 Item
对象是唯一的(就 equals()
而言)并且您可以从客户端获取它,您可以使事情变得更简单。
您可能只需要将 MenuItem
(叶子)中的方法定义为:
public void editItemName(String newName){
this.name = newName;
}
您可以定义一个按标识符存储项目的地图:
Map<String, MenuItem> mapUniqueItems = new HashMap<>();
// add items in the map
mapUniqueItems.put("item1", new MenuItem(..));
mapUniqueItems.put("item2", new MenuItem(..));
// add items in the hierarchy as you actually do
...
稍后您可以根据其 ID 编辑项目,例如:
String itemIdentifier = ...;
MenuItem item = mapUniqueItems.get(itemIdentifier);
item.editItemName("new value");