Java 面向对象学习一周小结

本文总结了Java的面向对象特性,包括面向对象与面向过程的区别、三大特征(封装、继承、多态)、构造函数、方法重载、匿名对象、封装、this关键字、静态成员、代码块、继承、super关键字、重写、接口、多态概念及其使用、异常处理等核心概念。深入探讨了类、对象、方法、权限修饰符和异常处理等方面,适合初学者巩固面向对象编程基础。
摘要由CSDN通过智能技术生成

面向对象基础

面向对象和面向过程的区别

面向过程:关注的执行过程,重在参与。
面向对象:关注的是功能的一个对象,执行者到指挥者的转变。
面向对象比较抽象,难以理解。
从更高的层次来进行对象的创建,更能贴近事物的一个本质。

面向对象的三大特征

封装:把一些实现的细节封装起来
继承:多个类把相同属性和行为形成一个总类,其他类用总类的属性和行为
多态:一种事物的多种形态。方法的重写

面向对象思想:

OOA:面向对象分析(Object Oriented Analysis)
OOD:面向对象设计(Object Oriented Design)
OOP:面向对象程序(Object Oriented Programming

方法定义格式

 权限修饰符 返回值类型 方法名(形式参数列表){ 
//方法体 
return 返回值; 
} 

栈、堆、方法区储存对象区别

栈存储的是:基本数据类型的数据 以及 引用数据类型的引用

堆存放的是:类的对象

方法区存放的是:类信息、 静态的变量 、常量、成员方法

构造函数

命名方法

方法名称必须与类名相同, 没有返回值类型的声明

作用

  • 初始化对象
  • 给类中的属性初始化

特点

  • 所有的java类中至少有一个构造方法
  • 如果类中没有写明构造方法,就会生成一个无参的构造方法
  • 方法名和类名相同,没有返回值类型

方法重载

特点:方法名相同,参数类型或参数长度或参数顺序不同,能否重载与与返回值无关

在不同的需求下,传递不同的参数调用方法完成具体功能

匿名对象

没有对象名称的对象 就是匿名对象

匿名对象只能使用一次,因为没有任何的对象引用,所以将称为垃圾,等待被GC回收

面向对象进阶

封装 private

为了避免值设置的逻辑错误,类中的属性都应设置为private,并提供setter和getter接口

this的作用

  • 调用类中的属性
  • 调用类中的方法或构造方法
  • 表示当前对象

this() :调用当前类中的构造方法
this(参数):有几个参数就调用当前几个参数的构造方法
this()必须放在构造方法的第一行上

static

  • 静态成员 在类加载时加载并初始化。
  • 无论一个类存在多少个对象 , 静态的属性, 永远在内存中只有一份( 可以理解为所有对象公用 )
  • 在访问时: 静态不能访问非静态 , 非静态可以访问静态

代码块

普通代码块

在执行的流程中出现的代码块 {}, 我们称其为普通代码块

构造代码块

在类中的成员代码块{}, 我们称其为构造代码块, 在每次对象创建时执行, 执行在构造方法之前

静态代码块

在类中使用static修饰的成员代码块 static{}, 我们称其为静态代码块, 在类加载时执行。 每次程序启动到关闭 ,只会执行一次的代码块

同步代码块

解决程序中不符合现实的规律(线程相关)

构造方法 与 构造代码块 以及 静态代码块的执行顺序

静态代码块 --> 构造代码块 --> 构造方法

权限修饰符

权限修饰符

面向对象高级

继承

格式

class 类名 extends 类名1{}

规范

  • 继承一个父类:单继承
  • 继承父类所有属性行为
  • 可以多重继承
  • 除了继承父类属性和行为,还可以拓展自己的

super

前提条件

在继承关系中

使用方法

super.属性名:调用父类属性
super():调用父类无参的构造方法

子类如果没有写构造方法,Java默认提供无参的构造方法
提供一个默认的super()调用父类无参的构造方法

super(参数):父类有参数的构造方法

位置:放在子类构造方法第一行

重写

前提条件

继承关系

规则

  • 参数列表相同
  • 返回类型相同
  • 访问权限不能比父类更低

override和overload的区别

  1. 发生的位置: 一个类中/子父类中
  2. 参数列表限制:必须不同/必须相同
  3. 返回值类型:与返回值类型无关/返回值类型必须一致
  4. 访问权限:与访问权限无关/子方法权限不能小于父
  5. 异常处理:与异常无关/异常范围要更小

抽象类

一个抽象类中可以没有抽象方法。抽象方法必须写在抽象类或者接口中。
格式:
abstract class 类名{ // 抽象类
}

原则

抽象类本身是不能直接进行实例化操作的,即:不能直接使用关键字new完成。

一个抽象类必须被子类所继承,被继承的子类(如果不是抽象类)则必须覆写(重写)抽象类中的全部抽象方法。

抽象类必须有子类才有意义,所以不能用==final==修饰;抽象类可以有构造方法,只是不能人为new出来,类中实现的部分实际上是封装起来

调用时都是要先调用父类中的构造方法(默认是无参的),之后再调用子类自己的构造方法)

抽象方法

只声明而未实现的方法称为抽象方法(未实现指的是:没有“{}”方法体),抽象方法必须使用abstract关键字声明

格式

abstract class 类名{ // 抽象类
public abstract void 方法名() ; // 抽象方法,只声明而未实现 
}

抽象类和普通类区别

  1. 抽象类必须用public或protected修饰(如果为private修饰,那么子类则无法继承,也就无法实现其抽象方法)。 默认缺省为 public

  2. 抽象类不可以使用new关键字创建对象, 但是在子类创建对象时, 抽象父类也会被JVM实例化。

  3. 如果一个子类继承抽象类,那么必须实现其所有的抽象方法。如果有未实现的抽象方法,那么子类也必须定义为 abstract类

接口

如果一个类中的全部方法都是抽象方法,全部属性都是全局常量,那么此时就可以将这个类定义成一个接口。

定义格式:

interface 接口名称{ 
	全局常量 ; 
	抽象方法 ; 
} 

接口中:只能使用全局常量,定义时可以省略public static final

抽象方法:定义时可以省略 public abstract

面向接口编程优点

  1. 降低程序的耦合性
  2. 易于程序的扩展
  3. 有利于程序的维护

接口的实现

格式

class 子类 implements 父接口1,父接口2...{ 
} 

接口的继承

接口因为都是抽象部分, 不存在具体的实现, 所以允许多继承,例如:

interface C extends A,B{ 
} 

注意:如果一个接口要想使用,必须依靠子类。 子类(如果不是抽象类的话)要实现接口中的所有抽象方法

接口和抽象类的区别

  1. 抽象类要被子类继承,接口要被类实现。
  2. 接口只能声明抽象方法,抽象类中可以声明抽象方法,也可以写非抽象方法。
  3. 接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
  4. 抽象类使用继承来使用, 无法多继承。 接口使用实现来使用, 可以多实现
  5. 抽象类中可以包含static方法 ,但是接口中不允许(静态方法不能被子类重写,因此接口中不能声明静态方法)
  6. 接口不能有构造方法,但是抽象类可以有

多态

概念

对象的多种表现形式

重载: 一个类中方法的多态性体现
重写: 子父类中方法的多态性体现

多态的使用

对象的类型转换

向上转型:将子类实例变为父类实例

父类 父类对象 = 子类实例 

向下转型:将父类实例变为子类实例

子类 子类对象 = (子类)父类实例

final

使用方法

  • 修饰变量

  • 修饰方法

     不能被重写 
    
  • 修饰类

     不能被继承
    

instanceof

作用

判断某个对象是否是指定类的实例,则可以使用instanceof关键字

格式

实例化对象 instanceof 类 //此操作返回boolean类型的数据

Object类

toString

建议重写Object中的toString方法。 此方法的作用:返回对象的字符串表示形式。 Object的toString方法, 返回对象的内存地址

equals

建议重写Object中的equals(Object obj)方法,此方法的作用:指示某个其他对象是否“等于”此对象。

实现了对象上最具区别的可能等价关系; 也就是说,对于任何非空引用值x和y ,当且仅当x和y引用同一对象( x == y具有值true )时,此方法返回true

内部类

广泛意义上的内部类一般来说包括这四种:
1、成员内部类 2、局部内部类 3、匿名内部类 4、静态内部类

成员内部类

class Outer {
private double x = 0; 
public Outer(double x) { this.x = x; 
} 
class Inner { //内部类 public void say() { 
System.out.println("x="+x); } 
}	
} 

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

不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问 的是成员内部类的成员。

如果要访问外部类的同名成员,需要以下面的形式进行访问:

外部类.this.成员变量
外部类.this.成员方法 

外部使用成员内部类 :

Outter outter = new Outter(); 
Outter.Inner inner = outter.new Inner(); 

局部内部类

 class Person{
    public Person() {
class Man{
    public Man(){
} 
public People getPerson(){
    class Student extends People{
		int age =0; } 
    return new Student();
}
} 

注意:局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。

匿名内部类

new 父类构造器(参数列表)|实现接口() 
{ 
//匿名内部类的类体部分
 } 

使用匿名内部类我们必须要继承一个父类或者实现一个接口,当然也仅能只继承一个父类或者实现一个接口。同时它也是没有class关键字,这是因为匿名内部类是直接使用new来生成一个对象的引用。当然这个引用是隐式的。

注意:

  1. 使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或 者实现一个接口。
  2. 匿名内部类中是不能定义构造函数的。
  3. 匿名内部类中不能存在任何的静态成员变量和静态方法。
  4. 匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
  5. 匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
  6. 只能访问final型的局部变量

静态内部类

public class Test {
  public static void main(String[] args)  {
  Outter.Inner inner = new Outter.Inner(); } 
}
class Outter {
   public Outter() {
} 
static class Inner {
    public Inner() {
} } 
} 

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。 静态内部类是不需要依赖于外部类对象的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员 变量或者方法

包装类

在这里插入图片描述

装箱:

基本数据类型转换成包装类

new integer(23)

拆箱:

包装类转换成基本数据类型

Double.doubleValue()

分类

  1. Number:Integer、Short、Long、Double、Float、Byte都是Number的子类表示是一个数字。
  2. Object:Character、Boolean都是Object的直接子类。

字符串转换

使用包装类还有一个很优秀的地方在于:可以将一个字符串变为指定的基本数据类型,此点一般在接收输入数据上使用 较多。

在Integer类中提供了以下的操作方法:

public static int parseInt(String s) :将String变为int型数据 

在Float类中提供了以下的操作方法:

public static float parseFloat(String s) :将String变为Float 

在Boolean 类中提供了以下操作方法:

public static boolean parseBoolean(String s) :将String变为boolean 

可变参数

一个方法中定义完了参数,则在调用的时候必须传入与其一一对应的参数,但是在JDK 1.5之后提供了新的功能,可以根 据需要自动传入任意个数的参数。

语法:

返回值类型 方法名称(数据类型...参数名称){ 
//参数在方法内部 , 以数组的形式来接收 
} 

注意:
可变参数只能出现在参数列表的最后。

异常处理

运行错误分为error和exception,我们处理的是exception,exception分为checkedexception可查异常和uncheckedexception不可查异常。 checkedexception是编译异常,uncheckedexception是RuntimeException运行时异常,存在不会出现下红线。

异常捕获写法

try{
// 有可能发生异常的代码段 
}catch(异常类型1 对象名1){
 // 异常的处理操作 
}catch(异常类型2 对象名2){ 
// 异常的处理操作 } ... 
finally{
// 异常的统一出口 
}  

特殊的多异常捕获写法

catch(异常类型1 |异常类型2 对象名){ //表示此块用于处理异常类型1 和 异常类型2 的异常信息 } 

try+catch的处理流程

  1. 一旦产生异常,则系统会自动产生一个异常类的实例化对象。
  2. 那么,此时如果异常发生在try语句,则会自动找到匹配的catch语句执行,如果没有在try语句中,则会将异 常抛出.
  3. 所有的catch根据方法的参数匹配异常类的实例化对象,如果匹配成功,则表示由此catch进行处理。

throws关键字

格式

返回值 方法名称()throws Exception{ 
} 

自定义异常类

编写一个类, 继承Exception,并重写一参构造方法 即可完成自定义受检异常类型。
编写一个类, 继承RuntimeExcepion,并重写一参构造方法 即可完成自定义运行时异常类型。

class MyException extends Exception{ // 继承Exception,表示一个自定义异常类 
public MyException(String msg){
super(msg) ; // 调用Exception中有一个参数的构造 
} }; 

自定义异常可以做很多事情, 例如:

class MyException extends Exception{
   public MyException(String msg){
super(msg) ; 
//在这里给维护人员发短信或邮件, 告知程序出现了BUG。 } 
}; 

异常处理常见面试题

  1. try-catch-finally 中哪个部分可以省略?
    答: catch和finally可以省略其中一个 , catch和finally不能同时省略
    注意:格式上允许省略catch块, 但是发生异常时就不会捕获异常了,我们在开发中也不会这样去写代码.

  2. try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
    答:finally中的代码会执行.

执行流程:

  1. 先计算返回值, 并将返回值存储起来, 等待返回
  2. 执行finally代码块 将之前存储的返回值, 返回出去;

需注意:

返回值是在finally运算之前就确定了,并且缓存了,不管finally对该值做任何的改变,返回的值都不会改变
 finally代码中不建议包含return,因为程序会在上述的流程中提前退出,也就是说返回的值不是try或 catch中的值
如果在try或catch中停止了JVM,则finally不会执行.例如停电- -, 或通过如下代码退出 :
JVM:System.exit(0); 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值