Java面向对象笔记

  • 前言
  • 1.基本概念
  • 1.1 包(Package)
  • 1.2 类(class)
  • 1.3 对象
  • 1.4 访问修饰符
  • 1.5 this关键字和super关键字
  • 1.6 static关键字
  • 1.7 构造方法
  • 1.8 方法重载
  • 1.9 对象的初始化顺序
  • 2. 封装
  • 2.1 概念
  • 2.2 实现
  • 3. 继承
  • 3.1 概念
  • 3.2 实现
  • 3.3 构造方法的调用
  • 3.4 方法重写
  • 4. 多态
  • 4.1 概念
  • 4.2 实现



前言

面向对象(Object Oriented Programming,OOP)程序设计中替代面向过程(Procedure Oriented Programming,POP)程序设计的一种程序设计方法。面向对象是一种程序的设计范型,是一种思想,使用 对象 的概念进行程序设计,世间万物皆可对象。

提到面向对象,自然会想到面向过程,面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一一实现,使用的时候依次调用就可以了。面向对象则是把构成问题的事务按照一定规则划分为多个独立的对象,然后通过调用对象的方法来解决问题。当然,一个应用程序会包含多个对象,通过多个对象的相互配合来实现应用程序的功能,这样当应用程序功能发生变动时,只需要修改个别的对象就可以了,从而使代码更容易得到维护。面向对象的特点主要可以概括为封装性、继承性和多态性。


1.基本概念

面向对象是一种符合人类思维习惯的编程思想。现实生活中存在各种形态不同的事物,这些事物之间存在着各种各样的联系。在程序中使用对象来映射现实中的事物,使用对象的关系来描述事物之间的联系,这种思想就是面向对象。

面向对象出现以前,结构化程序设计是程序设计的主流,结构化程序设计文称为面向过在的程序设计。面向过程的程序设计中,问题被看作一系列需要完成的功能模块,函数(泛指高级语言实现功能模块的实体)用于完成这些任务,解决问题的焦点是编写函数,函数是面向过程的,它关注如何依据规定的条件完成指定的任务。在多函数程序中,许多重要的数据被放置在全局数据区,这样它们可以被所有的函数访问(每个函数还可以具有它们自己的局部数据),这种数据和对数据操作相分离的结构很容易造成全局数据在未知的情况下被改动,因而程序的正确性不易保证。面向对象的程序设计将数据和对数据的操作行为封装在一起,作为一个相互依存、不可分割的整体——类。类中的大多数数据只能为本类的行为处理,类会提供公开的外部接口与外界进行通信。面向对象的程序模块间关系简单,程序的独立性高、数据安全。面向对象的显著特点包括:封装性、继承性和多态性。封装隐藏了内部实现,继承实现了现有代码的复用,多态在代码复用的基础上可以改写对象的行为。这些性质使软件具有良好的可重性,降低了开发和维护的成本。

java类的模板:

public class  类名 {
	//定义属性部分
    属性1的类型 属性1;
    属性2的类型 属性2;
	  …
    属性n的类型 属性n;
    //定义方法部分
    方法1;
    方法2;
      …
    方法m;
}

全局变量: 在类中定义的变量,称为全局变量,也就是属性;在整个类中都可以使用;有默认值,可以直接使用 。

局部变量: 除全局变量以外的其他变量,称为局部变量,如在方法 或 代码块中定义的变量;只能在局部访问;没有默认值,必须行赋值才能使用 局部变量和全局变量同名,局部变量优先级更高,即默认访问的是局部变量 。

全局变量局部变量的区别

  1. 在类中的位置不同
    成员变量:类中方法外
    局部变量:方法定义中或者方法声明上
  2. 在内存中的位置不同
    成员变量:在堆中
    局部变量:在栈中
  3. 生命周期不同
    成员变量:随着对象的创建而存在,随着对象的 消失而消失
    局部变量:随着方法的调用而存在,随着方法的 调用完毕而消失
  4. 初始化值不同
    成员变量:有默认值
    局部变量:没有默认值,必须定义,赋值,然后 才能使用

匿名对象
定义:没有名字的对象,在创建对象时,只通过new的动作在堆内存开辟空间,却没有把堆内存空间的地址值赋值给栈内存的某个变量用以存储。匿名对象其实就是对象,对象具有的功能匿名对象都具有,只不过有名字的对象可以重复使用,匿名对象只能用一次罢了。
使用:调用方法,仅仅只调用一次的时候;可以作为实际参数传递。
特点:由于我们没有记录堆内存对象的地址值,所以只能用一次,再次使用就找不到了;匿名对象的好处就是使用完毕就是垃圾,可以在垃圾回收器空闲时回收,节省内存空间。

main方法是静态的
public:权限最大
static:不用创建对象调用
void:返回值给jvm没有意义
main:就是一个常见的名称。
String[] args:可以接收数据,提供程序的灵活性
格式:java MainDemo hello world java
java MainDemo 10 20 30

1.1 包(Package)

作用: 区分同名的类 类较多时便于管理 便于访问控制 。

声明:用来指定当前类所在包 使用package,写法: package 包名; 必须位于第一行(注释除外) 。

命名: 采用组织的反向域名 使用小写字母,不能以点号开头或结尾 com.baidu.fanyi 。

导入:当需要使用其他包中的类时必须导入 使用import,写法: import 包名.类名; 或 import 包名.*; 必须位于包声明的下面。

常用的包: java.lang 包含Java的核心类,如System、String、Math等,该包默认会被自动导入,当使用其中的 类,无需import导入 java.util 包含实用的工具类,如Scanner、Arrays等 java.io, 包含输入/输出操作的类 java.sql, 包含数据库操作的类 ,java.net 包含网络操作的类 java.awt 包含图形窗口操作的类 。

注意:定义类务必指定包名,严禁将类直接放到src下(default package默认包),会导致类无法被引用。

1.2 类(class)

类是具有相同的特征和行为的一组对象的抽象

class 类名 { 
	//成员属性;
	public    公有成员;
	protected 保护成员;
	private   私有成员;
	default  默认成员;
	
	//构造方法;
	
	//成员方法;
}

公有成员可以自由访问;保护成员可以被子类访问;私有成员只能被本类访问; 默认成员可以被同一package中的类访问。

:一个类就是一个数据类型,定义一个类其实就是创建了一个数据类型 类名使用帕斯卡命名法,即所有单词首字母大写 一个文件中可以定义多个类,但只能有一个public修饰的类,且此类的名称必须与文件名相同。

属性:类的特征;定义方式: 数据类型 属性名; 属性名使用驼峰命名法,即第一个单词首字母小写,其他单词首字母大写。

方法:类的行为,对象执行的操作;定义方式:public 返回值类型 方法名(参数列表){ 方法体} 方法名使用驼峰命名法,且一般多使用动词。

1.3 对象

对象是类的实例
对象是根据类创建的,并且一个类可以对应多个对象。

//创建对象
// 方式1 
类名 对象名=new 类名(); 
// 方式2 
类名 对象名; 对象名=new 类名();

//访问对象
//访问对象的属性
对象名.属性名
//访问对象的方法
对象名.方法名()

1.4 访问修饰符

访问修饰符 用来控制访问范围,可以修饰属性、方法、类等

public:在哪都能访问
protected:只有不同包并且非子类不能访问,其他都能访问
private:只有本类中可以访问
默认:只有本包中可以访问
范围从大到小的顺序:public>protected>默认>private

1.5 this关键字和super关键字

可以使用this关键字来解决局部变量和全局变量同名的问题
this代表所在类的对象引用
this表示当前类的一个对象(方法被哪个对象调用,this就代表那个对象),只能在类的方法中使用,表示方法的调用者,即调用该方法的对象 当局部变量和全局变量同名时,可以使用 this。来访问全局变量 当局部变量和全局变量不同名时,可以省略不写 this。

super是一个指代变量,用于在子类中指代父类对象。
只能用于子类的构造函数和实例方法中,不能用于子类的类(静态)方法中。原因是super指代的是一个父类的对象,它需要在运行时被创建,而静态方法是类方法,它是类的一部分。当类被加载时,方法已经存在,但是这时候父类对象还没有被初始化。
在子类中调用父类的属性或方法。特别是子类中有与父类相同的属性或者方法,那么这时如果你想调用父类的属性或者方法,那么你必须使用super关键字。因为子类中和父类中的属性或方法同名,则父类中的方法或属性将被覆盖或隐藏。super可以指代父类中的类属性和类方法,但是并不建议这么用,虽然不会报错,但是说明对static关键字还不够了解。

1.6 static关键字

static表示静态的,可以用来修饰变量和方法,分别称为静态变量和静态方法。
静态变量 使用static修饰的变量,称为静态变量 或 类变量(非static修饰的变量称为实例变量) ; 静态变量为类的所有对象所共有,属于整个类 ;访问方式: 对象名.属性名 或 类名.属性名

静态方法 使用static修饰的方法,称为静态方法 或 类方法(非static修饰的方法称为实例方法); 访问方式: 对象名.方法名() 或 类名.方法名() ;静态方法中只能访问静态变量或静态方法,不能访问实例变量和实例方法 。

变量分类: 从作用域上划分:全局变量、局部变量;从变量所属上划分:实例变量、类变量。

static关键字
静态的意思。可以修饰成员变量和成员方法。

  1. 静态的特点:随着类的加载而加载;优先与对象存在;被类的所有对象共享这其实也是我们判断该不该使用静态的依据;可以通过类名调用既可以通过对象名调用,也可以通过类名调用,建议通过类名调用。
  2. 静态的内存图
    静态的内容在方法区的静态区
  3. 静态的注意事项;在静态方法中没有this对象;静态只能访问静态(代码测试过)

1.7 构造方法

构造方法是一种特殊的方法,也称为构造函数 或 构造器
作用:用于创建和初始化对象

格式:方法名和类名相同,没有返回值类型,连void都不能有,没有返回值。

//构造方法
	类名(){
	}

注意事项:如果我们没写构造方法,系统将提供一个默认的无参构造方法,如果我们给出了构造方法,系统将不再提供默认构造方法,如果这个时候,我们要使用无参构造方法,就必须自己给出。

推荐:永远手动自己给出无参构造方法。

当创建类的对象时,会自动调用构造方法 一个类中可以有多个构造方法(构造方法重载)

1.8 方法重载

一个类中包含两个或两个以上同名的方法,其参数不同,称为方法重载overload 在同一个类中

方法名相同 参数列表不同(参数个数、类型、顺序至少有一项不同),即方法签名不同 与方法修饰符、返回值类型、形参名无关

作用:提供同一种功能 的多种实现方式,根据调用者传递的参数来决定采用哪种方式

1.9 对象的初始化顺序

类加载 概念:将class文件读取加载到JVM内存中的过程,称为类加载

类加载的时机: 1. 创建类的对象 2. 调用类的静态属性或静态方法 3. 执行main方法时,main方法所在的类会被加载 4. 通过反射调用类 Class.forName(“包名.类名”)

类的成员 :属性(实例属性、静态属性);方法(实例方法、静态方法) ;构造方法

代码块 静态代码块:使用static修饰的代码块 注:static关键字可以修饰变量、方法、代码块、匿名类等

初始化顺序 步骤:1. 对象所在的类被加载 执行静态属性和静态代码块(根据定义的顺序,从上往下执行) 特性: 静态变量在类加载时初始化,且在内存中只分配一块空间 静态代码块在类加载时执行,且只执行一次(类只会被加载一次),主要用于初始化静态属 性静态代码块中不能初始化实例变量,只能初始化静态变量 ;2. 对象被创建 执行实例属性和代码块(根据定义的顺序,从上往下执行) 执行构造方法

总结:执行先后顺序: 静态代码块>代码块>构造方法

2. 封装

2.1 概念

将类的属性封装在类中,不允许在类的外部直接访问,保护数据的安全,使内容可控 只能通过被授权的方法才能对数据进行访问 。类的基本原则就是封装。

2.2 实现

实现方式 步骤:1. 将属性私有化 使用private修饰属性 。
2. 提供对外访问的方法,用于赋值、取值 使用public修饰方法
方法的命名规范:
赋值方法:以set开头,后面属性名,如setXxx,称为setter方法(属性名首字母大写)
取值方法:以get开头,后面属性名,如getXxx 如果是boolean类型属性,可以getXxx,也可以是isXxx

如果属性只具有getter方法,则表示该属性是只读的,在外部只能读取 。
如果属性只具有setter方法,则表示该属性是只写的,在外部只能修改。

3. 继承

3.1 概念

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。

可以让一个类继承自另一个类,此时该类会继承另一个类中的属性和方法 继承而得到的类称为子类,被继承的类称为父类(超类/基类) 继承是一种 is a 的关系。

3.2 实现

通过extends关键字可以实现类与类的继承
class 子类名 extends 父类名 {}

单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类。
有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员。

作用:代码复用:将多个子类中相同的属性和方法放到父类中 功能扩展:子类可以有自己独特的属性和方法

特性:Java只支持单继承,不支持多继承,但支持多层继承,即继承的传递 Java中所有的类都直接或间接的继承了java.lang.Object类

继承的范围:子类可以继承父类的哪些成员: 父类的public、protected、默认修饰的属性和方法可以被子类继承(同包的情况下) 父类的private修饰的属性和方法不能被子类继承 父类的构造方法不能被子类继承(构造方法名必须与类名相同,而子类名称不可能与父类相同)

3.3 构造方法的调用

调用过程: 创建子类对象时默认会自动调用父类无参的构造方法(此时必须要保证父类中有无参构造,否则会报错)
从子类开始,逐层往上调用父类的构造方法,直到Object类,然后再层层返回到子类中,执行后续代码 创建子类对象时必须会调用父类的构造方法,而调用父类构造方法也就创建了父类的对象,所以当创建 子类对象时,其实也创建了父类对象,只不过这个父类对象并不是独立存在的,而是和子类对象合为一 个整体 class 子类 extends 父类{ }

super关键字: 表示父类对象的引用,只能在子类中使用 可以使用 super() 调用父类的构造方法,必须位于第一行 可以使用 super. 访问父类的属性和方法,解决父类和子类中成员同名的问题 。

this关键字: 表示当前对象的引用,只能在方法中使用 可以使用 this() 访问当前类中重载的构造方法,必须位于第一行 可以使用 this. 访问本类中的属性和方法,解决全局变量和局部变量同名的变量 。

注:调用构造方法时this()和super()都只能放在第一行,所以不能同时使用。

3.4 方法重写

子类中的方法,与父类中的方法的名称、参数列表、返回类型一样,我们就说子类重写了父类的方法,称为方法重写。

在父子类中,方法名相同,参数列表相同,返回类型相同或是子类,访问修饰符不能缩小(即访问权限不能缩小),子类不能抛出比父类更大的异常。

作用:用来重新定义子类的行为,解决父类和子类的差异性 面试:方法重载和方法重写的区别

4. 多态

4.1 概念

3.1 概念多态是具有表现多种形态的能力的特殊,即一种事物,具有多种形态 回顾?基本数据类型之间的转换 自动类型转换 强制类型转换 引用类型之间的转换 3.2 引用类型之间的转换 两种:自动类型转换 将子类对象转换父类,如student——>Person 将父类的引用指向子类的对象,称为向上转型,会自动进行类型转换 特性: 通过父类引用变量调用的方法是子类重写后的方法,不是父类的方法 通过父类引用变量无法访问子类特有的属性和方法 强制类型转换 将一个指向子类对象的父类引用赋给一个子类的引用,称为向下转型,必须进行强制类型转换 语法: (子类类型)指向子类对象的父类引用 特性: 向下转型后,可以访问子类特有的属性和方法 必须转换为父类指向的真实子类类型,否则会出现类型转换异常ClassCastException 向下转型是不安全的,可以在转换时使用 instanceof 操作符判断对象的类型,避免类型转换异 常 3.3

4.2 实现

多态的实现:将父类作为方法形参,将子类的对象作为方法实参,从而实现多态 。

实现多态的条件: 继承的存在(继承是多态的基础,没有继承就没有多态) ,子类重写父类的方法(多态下调用的是子类重写后的方法),父类引用变量指向子类对象(向上转型)。

多态的优点: 减少代码量 ,提高可扩展性和可维护性。