Java 模型中的封装 Class
Encapsulation in the Java Model Class
假设我们开发了一个简单的博客网站后端,并且该应用程序具有三个或更多 POJO classes,例如 Post
、User
, Category
.
所有 class 具有相同的字段,例如 id
、createdDate
、updateDate
。
作为 java 程序员,我们使用 private
访问修饰符将 封装 应用于 class 中的所有字段。我的问题很简单:我们可以使用默认访问修饰符和继承执行封装吗?
代码:
public abstract class BaseModel {
String id;
LocalDateTime createdDate;
LocalDateTime updatedDate;
// getters and setters
}
public class Post extends BaseModel{
private String slug;
private String name;
private String title;
// other fields, getters and setters
}
public class Category extends BaseModel{
private String name;
private String slug;
// other fields, getters and setters
}
默认修饰符表示它只能在包中访问。因此,如果您在不同的包中使用 child class,将无法访问这些字段。
如果这是您想要的,太好了!封装好了。
如果这不是你想要的,那就太可惜了......但你仍然拥有受保护的修饰符。
这让我们 child class 继承字段,即使它在不同的包中。
也看到这个答案:What is the difference between public, protected, package-private and private in Java?
受保护的修饰符
通常的做法是使用 protected
访问修饰符来 封装 class [=] 中的成员48=]Parent class.
Package private 字段和方法对 subclasses 不可见 Parentclass。相反,任何 subclass 都可以访问 protected
变量和行为,无论其位置如何。
组合与继承
继承并不总是有益的,in-fact在很多情况下并非如此。在做出 class-design 决定之前,您需要考虑所有利弊,例如特定 class 是否会派生自另一个 class.
扩展BaseModel
的好处是什么?
这里的 多态性 似乎无法利用。因为您可以使用 parent 类型 BaseModel
的唯一行为是创建和更新日期的 getter 和 setter。同时您将无法访问 subclasses.
的特定行为
它看起来更像是一个缺点,因为 BaseModel
不是为扩展设计的 。 IE。它既不包含任何有用的实现(我没有考虑 getters/setters),它的子classes(即将是一个有利的 多态性 ) 的场景。
事实上,您扩展 BaseModel
只是为了重用几个变量。这不是利用 继承 .
的令人信服的理由
你的例子是用 HAS A[ 替换 IS A 关系(Post
是 BaseModel
)的完美案例=69=]关系(Post
包括BaseModel
)。
设计技术,当一个 class 包含其实例字段另一个 class 的实例而不是扩展此 class 时,称为 Composition.
一般来说,组合是比继承更可取的方法。除了继承之外,它还允许重用行为,同时 class 紧密耦合。
如果您使 BaseModel
成为具体的 class 并将 组合 应用于其他 class,您的代码将看起来像那样。
public class BaseModel {
private String id;
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
// getters and setters
}
public class Post {
private BaseModel base;
private String slug;
private String name;
private String title;
// other fields, getters and setters
}
public class Category {
private BaseModel base;
private String name;
private String slug;
// other fields, getters and setters
}
假设我们开发了一个简单的博客网站后端,并且该应用程序具有三个或更多 POJO classes,例如 Post
、User
, Category
.
所有 class 具有相同的字段,例如 id
、createdDate
、updateDate
。
作为 java 程序员,我们使用 private
访问修饰符将 封装 应用于 class 中的所有字段。我的问题很简单:我们可以使用默认访问修饰符和继承执行封装吗?
代码:
public abstract class BaseModel {
String id;
LocalDateTime createdDate;
LocalDateTime updatedDate;
// getters and setters
}
public class Post extends BaseModel{
private String slug;
private String name;
private String title;
// other fields, getters and setters
}
public class Category extends BaseModel{
private String name;
private String slug;
// other fields, getters and setters
}
默认修饰符表示它只能在包中访问。因此,如果您在不同的包中使用 child class,将无法访问这些字段。
如果这是您想要的,太好了!封装好了。
如果这不是你想要的,那就太可惜了......但你仍然拥有受保护的修饰符。
这让我们 child class 继承字段,即使它在不同的包中。
也看到这个答案:What is the difference between public, protected, package-private and private in Java?
受保护的修饰符
通常的做法是使用 protected
访问修饰符来 封装 class [=] 中的成员48=]Parent class.
Package private 字段和方法对 subclasses 不可见 Parentclass。相反,任何 subclass 都可以访问 protected
变量和行为,无论其位置如何。
组合与继承
继承并不总是有益的,in-fact在很多情况下并非如此。在做出 class-design 决定之前,您需要考虑所有利弊,例如特定 class 是否会派生自另一个 class.
扩展BaseModel
的好处是什么?
这里的 多态性 似乎无法利用。因为您可以使用 parent 类型 BaseModel
的唯一行为是创建和更新日期的 getter 和 setter。同时您将无法访问 subclasses.
它看起来更像是一个缺点,因为 BaseModel
不是为扩展设计的 。 IE。它既不包含任何有用的实现(我没有考虑 getters/setters),它的子classes(即将是一个有利的 多态性 ) 的场景。
事实上,您扩展 BaseModel
只是为了重用几个变量。这不是利用 继承 .
你的例子是用 HAS A[ 替换 IS A 关系(Post
是 BaseModel
)的完美案例=69=]关系(Post
包括BaseModel
)。
设计技术,当一个 class 包含其实例字段另一个 class 的实例而不是扩展此 class 时,称为 Composition.
一般来说,组合是比继承更可取的方法。除了继承之外,它还允许重用行为,同时 class 紧密耦合。
如果您使 BaseModel
成为具体的 class 并将 组合 应用于其他 class,您的代码将看起来像那样。
public class BaseModel {
private String id;
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
// getters and setters
}
public class Post {
private BaseModel base;
private String slug;
private String name;
private String title;
// other fields, getters and setters
}
public class Category {
private BaseModel base;
private String name;
private String slug;
// other fields, getters and setters
}