为什么有时需要先定义一个接口,然后再实现这个接口的实现类?

作者:Dion
链接:https://www.zhihu.com/question/20111251/answer/14012223
来源:知乎


接口是个规范”,这句没错。
“不如直接就在这个类中写实现方法岂不是更便捷”,你怎么保证这个接口就一个类去实现呢?如果多个类去实现同一个接口,程序怎么知道他们是有关联的呢?

既然不是一个类去实现,那就是有很多地方有用到,大家需要统一标准。甚至有的编程语言(Object-C)已经不把接口叫 interface,直接叫 protocol。

统一标准的目的,是大家都知道这个是做什么的,但是具体不用知道具体怎么做。


 

例如:

我知道 Comparable 这个接口是用来比较两个对象的,那么如何去比较呢?
数字有数字的比较方法,字符串有字符串的比较方法,学生(自己定义的类)也有自己的比较方法。

然后,在另外一个负责对象排序(不一定是数字喔)的代码里面,肯定需要将两个对象比较。
这两个对象是什么类型呢?
Object a,b?肯定不行,a > b 这样的语法无法通过编译。

int a,b?也不行?一开始就说了,不一定是数字。

....
所以,Comparable 就来了。他告诉编译器,a b 两个对象都满足 Comparable 接口,也就是他们是可以进行比较的。具体怎么比较,这段程序不需要知道。
所以,他需要一些具体的实现,Comparable 接口有一个方法,叫 compareTo。那么这个方法就是用来取代 <、> 这样的运算符。
因为运算符是编译器保留给内置类型(整数、浮点数)进行比较用的,而不是一个广义的比较运算。

如果你可以明白 JDK 自身库里面诸如 Comparable 这样已经有的接口,那么就很容易理解自己在开发程序的时候为什么需要用到接口了。

 

 

       有的时候,我参看源码,又会发现,很多时候,一个接口只有一个实现类,他还是要这么做,这样是不是真的就多此一举了呢?

      很抱歉,依然不是多此一举。在这里的作用是——项目协作,是项目模块化的利器。当你决定把一个类,仅仅给自己用,而且不打算再度扩展,那么这个时候,你可以选择不用接口+接口impl的形式。但是一旦你是进行一个团队合作的话,你就必须这么做。这个时候,接口就成为了一个约定,你的团队成员就无需在意你的代码细节,只需要关注于你的功能即可。说到这里,你是否可以想到,后台给你的东西,也叫接口?你再好好想想何为接口?难道后台返回给你所有的代码才是最合适的吗?我来替你总结一下,接口的作用之一:别人替你做了一些事,只给你你个调用口,你就可以成功地使用这个调用口,去得到他在背后默默地替你做的所有的操作所返回的结果。这,就是接口。


最后:

      简要说明interface和interfaceImpl还有调用者的关系。本来是调用者和类直接耦合了,现在是interface和interfaceImpl建立联系,interface和调用者建立联系,我们旨在减少调用者和类的直接联系,这叫封装,也叫信息隐藏

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Spring框架提供了多种方式来实现权限验证,其中最常用的方式是使用Spring Security框架。 下面是一个简单的Spring Security配置示例,实现了基于角色的权限验证: 1. 添加Spring Security依赖 ```xml <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>5.1.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>5.1.6.RELEASE</version> </dependency> ``` 2. 配置Spring Security ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user").password("{noop}password").roles("USER") .and() .withUser("admin").password("{noop}password").roles("ADMIN"); } } ``` 以上配置中,配置了一个基于角色的权限验证,只有拥有ADMIN角色的用户才能访问/admin路径下的资源。 3. 在Controller中使用注解进行权限验证 ```java @RestController @RequestMapping("/admin") public class AdminController { @GetMapping("/users") @PreAuthorize("hasRole('ADMIN')") public List<User> getUsers() { // ... } } ``` 以上示例中,使用了@PreAuthorize注解进行权限验证,只有拥有ADMIN角色的用户才能访问该接口。 当用户访问该接口时,如果没有ADMIN角色,则会返回403 Forbidden错误。 以上就是使用Spring Security实现权限验证的基本步骤。需要注意的是,这只是一个简单的示例,实际场景中可能需要更复杂的权限验证逻辑。 ### 回答2: Spring是一个开源的Java框架,提供了许多功能和特性,其中包括权限验证。要在Spring中实现权限验证,可以按照以下步骤进行: 1. 配置权限验证的依赖:在项目的构建文件中,例如pom.xml文件中,添加Spring Security依赖项。可以通过将以下内容添加到文件中来完成: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 2. 创建自定义的UserDetailsService:这是用于加载用户信息的接口。您可以根据需求实现接口,并覆盖其中的方法,以从数据库或其他数据源加载和验证用户信息。 3. 配置权限验证:在Spring的配置中,使用注解@EnableWebSecurity启用Spring Security,并在configure()方法中通过HttpSecurity对象进行权限配置。可以使用.antMatchers()方法来定义需要进行权限验证的URL路径,并使用具体的权限规则对其进行验证。例如: ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasAnyRole("ADMIN", "USER") .and() .formLogin() .and() .logout().permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 4. 创建用户角色和权限:在数据库或其他数据源中创建用户角色和权限的表,并相应地向其添加数据。确保用户表中包含用户名、密码和角色等必要字段。 5. 使用注解进行权限控制:在Controller或Service方法上使用Spring Security提供的注解,例如@PreAuthorize、@PostAuthorize和@PreFilter,指定用户所需的具体权限。例如: ``` @GetMapping("/admin") @PreAuthorize("hasRole('ADMIN')") public String adminPage() { return "adminPage"; } @GetMapping("/user") @PreAuthorize("hasAnyRole('ADMIN', 'USER')") public String userPage() { return "userPage"; } ``` 通过以上步骤,就可以在Spring中实现权限验证了。Spring Security会根据配置的规则和数据库中的用户角色和权限信息进行验证,确保只有具备相应权限的用户可以访问相应的资源。 ### 回答3: Spring提供了多种方式来实现权限验证,以下是其中一种常见的方法: 1. 配置权限验证规则:在Spring的配置文件中定义权限验证规则。可以使用Spring Security框架,通过在配置文件中定义角色和权限的对应关系,配置允许访问的路径和需要授权的路径。例如,可以通过`<intercept-url>`元素配置需要授权才能访问的URL,并指定需要的角色。 2. 使用注解进行权限验证:Spring提供了一系列注解,如`@Secured`和`@PreAuthorize`,用于在方法上进行权限验证。通过在方法上添加这些注解,并指定需要的角色或权限,可以在方法执行前进行权限检查。例如,使用`@Secured`注解可以指定需要的角色,而使用`@PreAuthorize`注解可以指定需要的权限表达式。 3. 自定义权限验证逻辑:通过实现Spring的`AccessDecisionVoter`接口,可以自定义权限验证逻辑。通过重`vote()`方法,可以根据需要的角色或权限进行验证,返回是否允许访问。然后,将自定义的权限验证器注册到Spring的安全配置中,使其生效。 4. 使用动态权限:有时,权限验证需要根据实际情况动态判断。在这种情况下,可以使用Spring的`SecurityExpressionHandler`接口实现动态权限验证。可以通过实现接口,并在`evaluate()`方法中编动态权限验证逻辑,返回是否允许访问。 总的来说,Spring提供了多种方式来实现权限验证,可以根据实际情况选择相应的方法。通过配置权限验证规则、使用注解进行权限验证、自定义权限验证逻辑以及使用动态权限,可以有效地实现权限验证功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值