自己在学习面向对象时get的重要点分享

1. 声明为static和private的方法不能被重写,但是可以被再次声明。

2. 重载和重写的区别

返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
在这里插入图片描述


3. final的使用

C:\Users\82169\AppData\Roaming\Typora\typora-user-images\image-20210309122437592.png


4. 继承

​ 子类继承父类的时候,父类在子类实例化过程中是并不会被实例化(创建对象)的。这里可以结合多态去理解!

​ 在创建一个子类实例对象的时候,你可以发现this和super指向的是同一个对象,子类构造器中调用的super(),只是为了给继承父类而来的属性初始化,从Object开始,执行final(父类编译时)、static(准备阶段,给默认值)、其静态代码块和静态初始化成员变量(初始化阶段)

​ 在JVM处理一条子类new对象的指令的时候:

  1. 首先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过(类加载过程),没有就去动态加载这个类;
  2. 在堆里分配一块内存空间给新建的这个对象,这些内存里值都默认是空值——对于基本类型的变量,默认的空值就是0或false,对于引用类型的变量默认的空值就是null;
  3. 然后去执行构造方法,构造器只是负责对java对象实例变量执行初始化(也就是赋初始值)

5. 抽象类
  1. 抽象类的修饰符必须用public或protected 修饰(如果为private修饰,那么子类则无法继承,也就无法实现其抽象方法)。默认缺省为 public
  2. 抽象类可以有构造方法,但是不能直接创建抽象类对象(不能new),而是通过抽象类的子类创建(子类通过super,JVM帮我们实例化),抽象类可以用多态
  3. 子类实现类必须覆盖重写抽象父类当中所有的抽象方法,否则子类还是抽象类
  4. 抽象类不一定有抽象方法,但是含抽象方法的类一定是抽象类
  5. 抽象类不能使用final声明,因为final属修饰的类是不能有子类的 , 而抽象类必须有子类才有意义,所以不能。

6. 接口

在这里插入图片描述

  1. 继承是优先于接口的实现的,当一个类继承的父类中的某一方法与该类实现的接口中的某一默认方法冲突时,优先使用父类的方法
  2. 如果一个类实现的多个接口中存在重复的抽象方法,则该类只需要对该方法覆盖重写一次;但是如果此时存在重复且冲突的默认方法,则该类必须对冲突的默认方法进行覆盖重写一次
  3. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误,这个变量必须手动赋值,不可以不赋值,也不可改变,变量名一般用完全大写的字母)
  4. 一般来说,接口中的方法不可以在接口中实现,只能在实现类中实现,(但是jdk1.8中新增的默认方法和静态方法、jdk1.9中私有方法可以)。

使用接口的好处:

  1. 降低程序的耦合性
  2. 易于程序的扩展
  3. 有利于程序的维护
  • 默认方法需要有defult修饰符
  • 普通私有方法,解决多个默认方法之间的重复代码问题
  • 静态私有方法,解决多个静态方法之间的重复代码问题

7. 抽象类和接口的区别
  1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行(JDK 1.8之后的默认方法可以用方法体,默认方法可以被覆盖重写;静态方法也可以有方法体,但是不能被实现)
  2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的
  3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法,JDK 1.8之后的版本可以含有静态方法了,接口可以直接调用,而接口的实现类对象不可以调用),而抽象类是可以有静态代码块和静态方法
  4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口(类与接口在继承上的区别)。

8. 多态
多态的定义:
	extends继承或者implement实现(类与类之间的继承、接口与接口之间的继承、类与接口之间的实现),是多态性的前提。
多态的使用:
	即对象的类型转换:向上转型和向下转型。
  1. 方法的重载和重写也是多态的一种, 不过是方法的多态(相同方法名的多种形态):
    1. 重载: 一个类中方法的多态性体现
    2. 重写: 子父类中方法的多态性体现
  2. 可以根据new的对象来调用自己的方法(注意这里是重写的方法,如果是子类特有的方法,在多态写法中无法使用,这种情况下就需要先向下转型),在使用成员变量的时候,如果是自己的成员变量,那么getter/setter方法就可以实现,这也是封装必须有的操作,不额外添加代码量,而使用父类的非私有成员变量的时候也可以直接调用,如果不用多态的话,那么这种情况的访问必须增加代码量来获取。

9. toString
Object类的toString方法返回的是一个字符串,该字符串由 :

对象所属的全路径类名称 + @符号+对象的哈希码(hashcode)的无符号十六进制表示形式。

10. ==、equals和hashcode
== 的使用:
 对于基本数据类型的变量,==比较的是数据内容;
 对于引用数据类型的变量,==比较的是内存的地址。
 
另外注意:Java中只有值传递
1.equals的使用(重写以比较引用数据类型):
 默认的equals方法从Object类中继承而来,底层还是使用了==,因此需要重写才能实现我们需要的功能。

2.equals的五个特性:自反性、对称性、传递性、一致性、非空性
    
3.标准的equals方法:
    @Override
    public boolean equals(Object o) {
    
        //第一步,直接使用==,同一个指向对象就true,提高效率
    	if (this == o) return true;
    
    	//第二步:判断是否为空,调用者可以成功调用肯定不是null了
    	//只需要判断传递过来的对象是否是空,也是提高效率用的
        if (o == null ) return false;
    
    	/*第三步:比较两者所属的类
    		(1)如果子类允许重写equals,那就用getClass() != o.getClass(),
    		(2)如果不允许重写equals,将equals设置成final,然后使用instanceof
    		
    	  原因:这是对称性要求的,这里要注意调用的equals方法是否一样
    	*/
    	if (getClass() != o.getClass()) return false;
    	//if (!(o instanceof ClassName)) return false;
        
    	//第四步:经过上面步骤,就比较具体的内容
    	Book book = (Book) o;
        return pageNum == book.pageNum && Objects.equals(title, book.title);
    }
//equals为什么如果子类允许重写equals,那就用getClass() != o.getClass(),
//如果不允许重写equals,将equals设置成final,然后使用instanceof?

class A{
	private String name;
	private int age;

}
class B extends A{
	private String name;
	private int age;
	private char sex;
}

//情况一:如果子类允许重写equals,我们使用instanceof的话
//A比较name、age
//B比较name、age、sex
B b = new B();//张三,18,男
A a = new A();//张三,18
a.equals(b)//true,字段数量都不一样怎么会一样?
b.equals(a)//false,很明显,A不是B类型的,对称性就说不通了呀!!
    
//情况一:如果子类不允许重写equals,我们使用getClass() != o.getClass()的话
//A和B的equals方法都是比较name、age
B b = new B();//张三,18,男
A a = new B();//张三,18,女
a.equals(b)//true
b.equals(a)//false
//注意:
//(1)这里B调用的只能是自己重新声明的equals而不是A的equals
//(2)B重新声明的equals中需要比较的字段多,a缺少了sex字段,也不行
    
hashcode方法:
    默认是调用Object类定义的,返回的是根据对象的地址值(逻辑地址)得到的散列码。

注意:
    如果需要使用HashSet存储自定义类型元素(set集合需要保证元素唯一),那么必须保证存储的元素(String、Integer、Person...)重写了hashCode方法和equals方法,**否则不可能相等的!!!**
	
重写hashcode方法:调用Objects工具类的hash方法
    @Override
    public int hashCode() {
        return Objects.hash(title, pageNum);
    }

10.内部类
1.成员内部类的特点

	(1)成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员);

	(2)当成员内部类拥有和外部类同名的成员变量或者方法时,默认情况下访问的是成员内部类的成员。
	
	(3)成员内部类调用外部类:外部类.this.成员变量/成员方法
	
	(4)外部类调用成员内部类:外部类.成员内部类 对象名 = 外部类的对象.new 成员内部类();
2.局部内部类的特点

	局部内部类就像是方法里面的一个局部变量一样,是**不能有public、protected、private以及 static修饰符**的。
3.匿名内部类的特点
	(1)使用匿名内部类的时候如果要实现接口,那么只能实现一个;
	
	(2)没有构造方法(只使用一次,不需要了)
	
	(3)不能是抽象的(本来就只使用一次,后面都创建不了实现类)
	
	(4)只能访问final型的局部变量(局部内部类也是,匿名内部类是局部内部类的进一步简化,原因在于局部内部类会被单独生成一个字节码文件,如果改动的话,会发生逻辑错乱)
		
	注意!!!!
	jdk1.8有个特性,如果你的final型变量能够保证只赋值一次,不再改变,final关键字就可以省略不写。
	
4.静态内部类的特点
	(1)使用static修饰符修饰 
	
	(2)和调用成员内部类很像: 外部类.静态内部类 inner = new 外部类.静态内部类();
	
	(3)和成员内部类的区别:
			1.调用成员内部类需要先创建外部类,而调用静态内部类不需要,因为是静态的;
			2.静态内部类不能使用外部类中非静态的东西。

11.包装类(JDK 1.5之后有自动装箱、拆箱)

12.异常
1.异常体系(Throwable的两个子类):
	(1)Error错误:表示的是错误,是JVM发出的错误操作,只能尽量避免,无法用代码处理。
	(2)Exception异常:一般表示所有程序中的错误,所以一般在程序中将进行try…catch的处理。
		(1)运行期异常:运行期间发生的
		(2)编译器异常:受检查的,编译器会帮我们检查

2.throw和throws区别:
	(1)throws此关键字主要在方法的声明上使用,表示方法中不处理异常,而交给调用处处理;
	(2)throw关键字表示在程序中人为的抛出一个异常。 //throw new Exception(xxx);
	
	**注意:异常出现的时候JVM会自动实例化一个异常对象,不管你是否人为抛出,都已存在了,但是你抛出的异常可以自己选择,也就是说我们捕获这个异常之后怎么处理使由我们确定的。
	
3.捕获异常(try-catch的使用):
	(1)一个try(一个异常)、一个catch
	(2)一个try(多个异常,也可以直接写父类异常)、一个catch:进行一次处理
	(3)一个try(多个异常)、多个catch(此时子类在前,父类在后,不然永远都只执行父类异常),多次处理
	(4)父类没有抛出,子类也不能抛出;父类抛出了异常,子类必须抛出相同的或者该异常的子类

4. try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
	答:finally中的代码会执行
	
    执行流程:
    	(1)先计算返回值, 并将返回值存储起来, 等待返回
   	    (2)执行finally代码块
    	(3)将之前存储的返回值, 返回出去;
    需注意:
    	(1)返回值是在finally运算之前就确定了,并且缓存了,不管finally对该值做任何的改变,返回的值都不会改变
    	(2)finally代码中不建议包含return,因为程序会在上述的流程中提前退出,也就是说返回的值不是try或catch中的值
    	(3)如果在try或catch中停止了JVM,则finally不会执行.例如停电、程序关闭了等等, 或通过如下代码退出:
    			JVM:System.exit(0);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值