面向对象的特征
- java面向对象的三大特征是什么?
封装、继承、多态。 - 封装
把属性和方法隐藏起来,只保留一些对外的接口和外部进行交互。 - 继承
子类继承父类的特征和行为,使得子类具有父类的非private属性和方法。 - 多态
多态就是同一个接口,使用不同的实现,而执行不同的操作。 - 抽象
将一类对象的共同特征总结出来构造类的过程,数据抽象指的是属性,行为抽象指的是方法。
抽象类与接口
- 抽象类
1)抽象类是用来捕捉子类的通用特性的
2)它不能被实例化,只能被用作子类的超类
3)抽象类是被用来创建继承层级里子类的模板
- 接口
1)接口是抽象方法的集合
2)如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法
3)如果实现了这个接口,那么就必须确保使用这些方法
4)接口只是一种形式,接口自身不能做任何事情
- 抽象类和接口的对比
参数 | 抽象类 | 接口 |
---|---|---|
默认的方法实现 | 它可以有默认的方法实现 | 接口完全是抽象的。它根本不存在方法的实现 |
实现 | 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 | 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现 |
构造器 | 抽象类可以有构造器 | 接口不能有构造器 |
与正常Java类的区别 | 除了你不能实例化抽象类之外,它和普通Java类没有任何区别 | 接口是完全不同的类型 |
访问修饰符 | 抽象方法可以有public、protected和default这些修饰符 | 接口方法默认修饰符是public。你不可以使用其它修饰符。 |
main方法 | 抽象方法可以有main方法并且我们可以运行它 | 接口没有main方法,因此我们不能运行它。 |
多继承 | 抽象方法可以继承一个类和实现多个接口 | 接口只可以继承一个或多个其它接口 |
速度 | 它比接口速度要快 | 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。 |
添加新方法 | 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 | 如果你往接口中添加方法,那么你必须改变实现该接口的类。 |
内部类
- 概述
1)把类定义在另一个类的内部,该类就被称为内部类
2)把类Inner定义在类Outer中,类Inner就被称为内部类
- 访问规则
1)可以直接访问外部类的成员,包括私有
2)外部类要想访问内部类成员,必须创建对象
- 分类
1)成员内部类:位于外部类成员位置的类,可以使用外部类中所有的成员变量和成员方法(包括private的)
2)局部内部类:定义在一个方法或者一个作用域里面的类,主要是作用域发生了变化,只能在自身所在方法和属性中被使用
3)静态内部类:用static修饰的内部类,不能使用外部类的非static成员变量和成员方法
4)匿名内部类:一个没有名字的类,是内部类的简化写法,其实是继承该类或者实现接口的子类匿名对象
重载与重写
- 方法重载
1)同一个类中的多个方法具有相同的名字,这些方法具有不同的参数列表
2)参数类型和个数不一样,返回值类型可以相同也可以不相同
3)无法以返回型别作为重载函数的区分标准
4)重载Overloading是一个类中多态性的一种表现。
- 方法重写
1)子类定义的方法与父类中的方法具有相同的方法名字,相同的参数表和相同的返回类型
2)子类中不能重写父类中的final方法
3)子类中必须重写父类中的abstract方法
hashCode()和equals()方法的联系
相等(相同)的对象必须具有相等的哈希码(或者散列码)。
如果两个对象的hashCode相同,它们并不一定相同。
final, finally, finalize的区别
- final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
- finally是异常处理语句结构的一部分,表示总是执行。
- finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
Comparable和Comparator接口的作用以及区别
- Comparable接口包含compareTo()方法。这个方法可以个给两个对象排序。
- Comparator接口包含compare()和equals()方法。
- compare()方法用来给两个输入参数排序,返回负数,0,正数表明第一个参数是小于,等于,大于第二个参数。
- equals()方法需要一个对象作为参数,它用来决定输入参数是否和comparator相等。
- 只有当输入参数也是一个comparator并且输入参数和当前comparator的排序结果是相同的时候,这个方法才返回true。
Java是否支持多继承
- Java中类不支持多继承,只支持单继承(即一个类只有一个父类)。
- 但是java中的接口支持多继承,,即一个子接口可以有多个父接口。
- 接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能。
- 当类实现接口时,类就扩展了相应的功能。
extends 和super 泛型限定符
- 泛型中上界和下界的定义
1)上界<? extend Fruit>
2)下界<? super Apple>
- 上界和下界的特点
1)上界的list只能get,不能add(确切地说不能add出除null之外的对象,包括Object)
3)下界的list只能add,不能get
1 | import java.util.ArrayList; |
- 上界<? extend Fruit> ,表示所有继承Fruit的子类,但是具体是哪个子类,无法确定,所以调用add的时候,要add什么类型,谁也不知道。但是get的时候,不管是什么子类,不管追溯多少辈,肯定有个父类是Fruit,所以,我都可以用最大的父类Fruit接着,也就是把所有的子类向上转型为Fruit。
- 下界<? super Apple>,表示Apple的所有父类,包括Fruit,一直可以追溯到老祖宗Object 。那么当我add的时候,我不能add Apple的父类,因为不能确定List里面存放的到底是哪个父类。但是我可以add Apple及其子类。因为不管我的子类是什么类型,它都可以向上转型为Apple及其所有的父类甚至转型为Object 。但是当我get的时候,Apple的父类这么多,我用什么接着呢,除了Object,其他的都接不住。
什么是泛型
- 泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?
- 顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
1 | public class GenericTest { |
- 采用泛型写法后,在//1处想加入一个Integer类型的对象时会出现编译错误,通过List
,直接限定了list集合中只能含有String类型的元素,从而在//2处无须进行强制类型转换,因为此时,集合能够记住元素的类型信息,编译器已经能够确认它是String类型了。