博客主页:hyhWTX的博客主页
欢迎关注🖱点赞🎀收藏⭐留言✒
本文由hyhWTX原创,csdn首发!
系列专栏:面试题解
🀄如果觉得博主的文章还不错的话,请三连支持一下博主哦
题目八
抽象类和接口的理解
解析过程
讲真的,学了这么久的java,也接触了很多的项目代码,手敲了不少。突然看到这个,觉得这玩意很基础,没啥要理解的,学过了就记住了。
可是,当我坐在椅子上看着代码发呆的时候,突然意识到了一件事。我学到了抽象类以及接口也不在少数,可是当真正着手做项目开发的时候,用到的次数可以说是屈指可数。
当我仔细回想了一下,发现在开发过程中,如果是书写业务逻辑的话是用不到的,当做到一些关于底层架构的封装,或者一些工具的封装,才会遇到一些规则统一规范的定义。这样才会用到抽象的东西,否则的话写一些具体的业务逻辑基本上用不到抽象的东西。知识点虽然简单,是学过,但是学过和能够实践使用并且能够应用的合理是两回事。
这两个东西如何去看呢?,首先我们要去看看抽象类和接口本身的知识,从而去讨论在什么样的场景下去使用。首先来看这个知识点并不是很难,
下面是两个基本结构,一个是抽象类的结构,一个是接口的结构。
public interface Test08 {
}
public abstract class Test08 {
}
这两个怎么去记忆呢?很简单,当作是一个普通类结构去思考,去思考什么呢?第一件事就是首先你要明确里面有什么?对吧,因为一个基本的类里面,它首先有的就是描述一些成员啊什么的,。第二件事就是去思考怎么用,如何去使用呢?每一个类都得要去创建对象,对象调用之类的。第三件事就是它与其他类的关系。
就抽象类而言,第一件事来看,它里面有的是不是一些像属性,方法,构造方法,块这样的东西。那么这样来看,它是不是和具体类差不多?唯独它可以多一个抽象方法
抽象类举例
public abstract class Test08 {
// 属性
// public String name;
// public static String name;
public final String name = "";
/*// 普通方法
public void method(){
}*/
// 静态普通方法
public static void method(){
}
// 静态代码块
static {
}
//抽象方法
public abstract void abstractMethod();
// 构造方法
public AbstractClass(){}
}
当多了一个抽象方法的时候,会发现前面的修饰符不能随便来了,比如说上例中的抽象方法,你加一个private就不行了,(受保护之前的修饰符均可以,只有私有修饰符的不可以),因为抽象方法它的要求就是必须要让子类添加具体实现,当你使用私有修饰符的话,子类就无法访问到,就没有办法去修改了,那么这个方法是不是就没用了?这是不被允许的。除此以外,抽象类方法是不能加静态修饰符,因为我们都知道,静态方法属于类的,与对象无关,就不存在子类重写这个说法,那么你的子类不能重写,不能更改,里面的东西还没法使用。所以这样是不可以的。当然了,加上final也是不可以的,因为我们学过都是知道的,final表示的是最后的,是不让你进行修改的,但是有要求必须子类修改,从而变成宇哥具体方法能够重写。所以final也是不可以的。所以,当你使用抽象方法的时候,你只能在其前面添加一个权限符,而且还不能是私有权限,必须要能让子类访问到,能进行修改才可以的。
当然,你也可以在里面去书写构造方法,没有权限修饰符的限制。要注意的是不能去new。抽象类其实是有构造方法的,但是却不让它直接去调用对象。
接下来来看和其他类的关系,类的关系体现:一种是is-a,一种是has-a,还有一种叫use-a的关系。
对于抽象类而言,它是可以直接去继承另外一个抽象类的,抽象类可以直接继承另外一个普通类(虽然不常见)。具体类是可以继承抽象类的,但是是需要添加方法的,而且抽象类也是可以直接实现接口的,并且可以多实现。
接口举例
public interface Test08{
//属性
public static final String name = "";
// 方法 jdk8以前的
public abstract void test();
// 方法。jdk8以后的
default void aaa(){}
static void bbb(){}
}
接口相对而言还是比较浅显的,接口它相当于是比抽象类还要抽象,它里面的成员就只有那么几个方法,属性也有,但是它只能是静态的final修饰的属性。方法它也只能是公有的方法,在JDK8之后,出现了两种书写方式。这两种的出现使得抽象类和接口从语法上就很像了,在这里面可以写具体的方法。所以更加建议的是写接口而不是抽象类。接口是没有代码块和静态块,也没有构造方法。
从成员来看接口能够有的东西就与创建类完全不大一样,如何去使用?调用通过对象去调用
对于接口而言,它就比较特殊,它只能多继承另外的接口,接口是不能实现别人的,也不能写具体的关系。
题目九
如何正确理解泛型?
解析过程
说实话,泛型这个东西我们平时开发的过程中经常使用,使用的也是我们常说的定义泛型,所以问题来了,我们什么时候去定义?当我们去做一些底层的架构,封装的工具类的使用,才会使用到泛型的定义。
**泛型:**规范或者规定一些类型的意思,就是当你在定义一些或者描述一个类的时候,发现这个类当中可能需要一个类型,但是有个问题,你此时还不知道,所以这是个时候就需要先使用一个假的东西,一个符号去代替它。这个就是泛型的意思。
通常在哪里能够描述泛型呢?有两个地方,一个是在类的结构上描述,第二个通常是在方法的结构上描述,就是我只有方法结构,没有类本身,也可以描述泛型。
具体举例如下:
/**
*自己创建的一个类,或者说是自己描述的一个工具,给装东西用的,装的是什么,我们不确定,所以为了避免之后会有还得去规范类型的麻烦,使用一个符号去代替它<T>
* 当你未来使用的时候,你只需要告诉我这个T是个什么类型的,是String,还是int之类的。我就可以帮你改成你想要的那个对应的类型
*
* 某一个具体的方法使用到了泛型,别处不需要使用,此时就可以在方法里面去定义
*/
//类下的泛型,在类下面都可以使用
public class Box<T> {
// 属性
private T data;//这个T代表的是你未来要使用的类型
//某一个具体的方法使用到了泛型,别处不需要使用,此时就可以在方法里面去定义,此处建议大家回头看一下方法的结构,在此不作过多赘述
//需要在方法内部去定义一个泛型,就需要在修饰符以及返回值类型的中间的位置,在方法内部需要这样的一个定义类型,具体的使用时候自己决定
//比如说参数里面使用到了,或者说是返回值里面使用到了(在使用的时候需要更改你所要返回的类型),在方法里面定义的泛型与类和其他业务没有关系,如下在方法中定义了泛型,在方法之外是无法使用的,
// 有点像那个啥,局部变量的意思,内部使用,外边看不到
public static<T> void test(){
}
}
定义泛型并不难,难的是我们在使用泛型的时候,相对性来说比较麻烦。但是使用泛型本身也不麻烦,难得是一些通配符。
举例如下:
/**
*当作一个容器,装一个变量
*/
public class Box <T>{
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
public class MyUtil {
//设计一个方法,用来去显示Box
public static void showBox(Box box){
System.out.println(box.getData());
}
}
public class Test09 {
public static void main(String[] args) {
//主方法里调用使用
Box<String> box1 = new Box();//人为规定类型,使用泛型
//具体调用方法
box1.setData("zzz");
//不同的第一泛型可以存储不同的数据类型
Box<Integer> box2 = new Box<>();
box2.setData(123);
Box<Double> box3 = new Box<>();
box3.setData(3.1256);
//创建工具类
MyUtil.showBox(box1);
MyUtil.showBox(box2);
MyUtil.showBox(box3);
}
}
如上是一些正常的使用泛型,除此以外,我们平时还有见到一些泛型中带有一些标识符的,或者叫通配符。
比如说我们见到的如:
- <?>,通常在方法当中可能会见到一些参数这样传输。什么意思呢?就是你这个类当中定义的类型,只要是曾经在这里定义过的类型,传进来都是可以使用的,这个问号相当于是所有类型。
- <? extends 类>,这个叫什么呢?这个叫做上限通配符,就是说明以后所有的类都得比这个类小,叫做上限通配符,一种小于等于的感觉。
- <? super 类>,那么,这个叫做什么呢?细心的读者已经看到了,这个与上面的有点类似。没错,它就是下限通配符,就是说明以后以后的所有的类都得比这个类大,一种大于等于的感觉。
🎧最后的话,作者是一个新人,在很多方面还做的不好,欢迎大佬指正,一起学习哦,冲冲冲