java基础学习(八):Object类、抽象类、接口、访问权限修饰符
目录
- 一、Object类
- 1. 方法
- 2. hashCode()
- 二、访问权限修饰符
- 三、抽象类
- 四、接口
- 1. 实现
- 五、内部类
一、Object类
Object类是java中最大的类,所有的类都会直接或间接的继承Object。
1. 方法
equals()
:比较内存地址指向是否相同
hashCode()
:获取类的散列码,散列码根据地址生成
getCalss()
:获取类信息 反射领域
notify()
:唤醒等待的线程
wait()
:让线程进入等待状态,让出CPU和锁(在多线程场景下使用)
toString()
:输出对象的类型和内存地址
public static void main(String[] args) {Object obj = new Object();obj.equals(obj);obj.hashCode();obj.getClass();obj.notify();obj.wait();obj.toString();
}
这几个方法,其他的类都可以调用。
2. hashCode()
根据地址生成一个关键值(key值),根据关键值,会有一个算法,决定分配到哪个位置。
public static void main(String[] args) {Cat cat = new Cat();Cat cat2 = new Cat();System.out.println(cat.hashCode()); //输出:366712642System.out.println(cat2.hashCode());//输出:1829164700String res = "demo";String res2 = new String("demo");System.out.println(res.hashCode()); //输出:3079651System.out.println(res2.hashCode());//输出:3079651
}
根据输出可以看出:
- Cat类两个散列码不同;
- String类两个指向的不是同一个空间,但散列码确实相同的;
- 因为,对hashCode()进行了重写;而Cat类调用的是hashCode()没有重写,调用的是Object中的方法。
hashCode()和equals()的区别:
- equals()方法是判断这两个对象是否为同一对象,两个对象指向的是不是同一地址;
- hashCode()方法是判断这两个对象是否为同一类,上述示例中两个都是同一类 - 字符串
- 如果两个对象相同,equals()为true,那么它们的hashCode值一定相同;
- 如果两个对象不同,那么它们的hashCode值可能相同,也可能不同;
- 如果hashCode值相同,它们可能相同,也可能不同;
- 如果hashCode值不同,它们肯定不同。
二、访问权限修饰符
访问权限修饰符有四类:public、protected、private、不写默认,修饰变量、方法,都有谁可以访问到。
修饰符 | 当前类 | 不在同一类,但在同包下 | 子类 | 其他包 |
---|---|---|---|---|
public | √ | √(通过类名.变量名访问) | √(通过类名.变量名访问) | √ |
protected | √ | √ | √ | × |
不写默认 | √ | √ | × | × |
private | √ | × | × | × |
三、抽象类
- 关键字:
abstract
,目的:为了重写 - 抽象类中才能有抽象方法,非抽象类中不能有抽象方法
- 抽象类中可以有普通方法,抽象类可以没有抽象方法
- 抽象类中有构造方法
- 抽象类的子孙后代强制重写抽象方法
- 子类继承抽象类,若不想实现抽象类中的抽象方法,那么该类必须是抽象类(子类不想重写,将自己也变成抽象类)
- 抽象类不能创建对象,但是可以使用多态(与
new
有冲突)- 因为,
new
只能开辟具体类的空间,不能开辟抽象类的空间
- 因为,
final
不能和abstract
同时使用- 因为,
final
不支持继承重写,而抽象类强制子类重写
- 因为,
private
不能和abstract
同时使用- 因为,
private
只能在该类下访问,子类访问不到
- 因为,
static
不能和abstract
同时使用- 因为,
static
针对类,在类加载进内存的时候就要有空间,抽象类依靠子类重写,abstract
针对对象
- 因为,
示例:
- 父类Animal类中有一个run()方法,方法中输出:动起来
- 子类Cat类重写run()方法,方法中输出:跑起来
- 子类Fish类也重写run()方法,方法中输出:游起来
- 由此,可以看出,当父类中的方法,在子类中都重写;
- 那么,父类中的run()方法,可以不写具体的逻辑,去掉具体的逻辑,会报错;
- 因此,改为抽象方法,但依然报错,因为抽象方法只有在抽象类中存在,所以,要将父类Animal类改为抽象类
public abstract class Animal {public abstract void run();
}
四、接口
接口是比抽象类更抽象的存在。
- 关键字:
interface
- 接口中所有方法默认是
public abstract
修饰,都是抽象方法public interface Animal {//在接口中,写不写abstract,都是抽象方法public void run();public void eat(); }
- 接口中的所以变量默认是
public static final
修饰 - 接口中不可以直接
new
对象 - 接口中没有构造方法
- 实现接口的类必须实现接口中的所有方法,如果不实现,那么该类为抽象类
- 接口存在多态
- 接口和类之间叫实现(实现与继承意思一样):
implements
;类和类之间、接口和接口之间叫继承:extends
- 接口中存在多实现,用逗号隔开
public class Cat implements Animal,A{ }
- 接口存在多继承
- 继承类和实现接口可以同时存在
- Demo类
public class Demo { //Demo类 }
- A接口类和B接口类
- 可同时有BBB方法,因为没有具体的逻辑,没有冲突,所有在接口中有多继承
public interface A extends B {public void AAA();public void BBB();public void CCC(); }
public interface B {public void BBB(); }
- 小猫Cat实现类继承了Demo类并实现了Animal和A接口
public class Cat extends Demo implements Animal,A{@Overridepublic void run() {// TODO Auto-generated method stub}@Overridepublic void eat() {// TODO Auto-generated method stub}@Overridepublic void AAA() {// TODO Auto-generated method stub}@Overridepublic void BBB() {// TODO Auto-generated method stub}@Overridepublic void CCC() {// TODO Auto-generated method stub} }
- Demo类
1. 实现
- 接口和类之间叫实现(继承的另一种说法)
- 关键字:
implements
- Cat类实现Animal类,必须要重写Animal类中的抽象方法
public class Cat implements Animal{@Overridepublic void run() {// TODO Auto-generated method stub}@Overridepublic void eat() {// TODO Auto-generated method stub}}
- 如果不想写抽象方法,将自己变为抽象类
public abstract class Cat implements Animal{ }
五、内部类
- 写在类里的类,叫内部类
- 内部类的变量使用
private
修饰 - 内部类数据不能被外人访问,只有在当前类中访问(例如:Test类中的XiaoMing内部类,只能在Test类中访问)
- 可以使用方法访问内部类
public class Test {class XiaoMing{//内部类private String name = "小明";private String show() {return "小明";}}//使用方法访问内部类public String showMsg() {XiaoMing xiaoMing = new XiaoMing();return xiaoMing.show();}public static void main(String[] args) {Test test = new Test();System.out.println(test.showMsg());} }
- 借助内部类可以实现多继承
- 定义两个外部类
public class HuaJia {public void hua() {} }
public class ShuFa {public void xie() {} }
- 定义一个类,使用内部类实现多继承
public class Test {//实现多继承class HuaJiaA extends HuaJia{}class ShuaFaA extends ShuFa{}public void xie() {ShuFa shuFa = new ShuFa();shuFa.xie();}public void hua() {HuaJia huaJia = new HuaJia();huaJia.hua();}public static void main(String[] args) {Test test = new Test();test.hua();test.xie();} }
- 定义两个外部类
- 内部类分为:非静态内部类(也称为成员内部类)、局部内部类、匿名内部类、静态内部类