Java基础入门(七)之面向对象一
定义:是一种看待问题的思维方式 着眼于找到一个具有特殊功能的具体个体然后委托这个个体去做某件事 我们把这个个体 就叫做 对象是一种更符合人类思考习惯的思想(懒人思想)可以将复杂的事情简单化 将程序员从执行者转换成指挥者使用面向对象进行开发 先要去找到具体实现某功能的那个对象 如果该对象不存在 那么就创建一个具有所需功能的对象
类的定义:一个具有特殊功能的实体的集合(群体) 类是java语言最基本的单位
对象的定义:在一个类中 一个具有特殊功能的实体 能够解决特定的问题 对象 也被称为实例
类与对象之间的关系 类是对象的模板 对象是类的具体实现 java中描述事物通过类的形式体现 类是具体事物的抽象 对象即是该类事物实实在在的一个个体
类的声明
语法:权限修饰符 class 类名{
//类体
}
说明:
.访问权限修饰符 只能是 public 或者 默认(default)
.类名只要是一个合法的标识符即可 要求首字母必须大写
.尽量使用单个或者多个有意义的单词来命名
注意:
.一个java文件中可以写多个类编译后会生成多个.class字节码文件
.一个java文件中最多只能有一个被public修饰的类 该类的名字 必须和 java源文件名保持一致
.一个java文件中如果只有一个类 并且该类不是用public修饰的类名 和 java文件名可以不一样
- 类中成员变量的定义 通过对象引用.成员变量名 的方式进行调用
成员变量和局部变量的区别:*******
A:初始化值不同 成员变量:有默认初始化值
局部变量:没有默认初始化值 必须赋值
B:在类中的位置不同 成员变量:在类中 方法外
局部变量:在方法中 或者 方法声明上
C:在内存中的位置不同
成员变量:在堆内存中(属于对象 对象存在堆内存 它就也在堆内存)
局部变量:在栈内存中(属于方法 方法进栈)
D:生命周期不同
成员变量:随着对象的创建而存在 随着对象的消亡而消亡
局部变量:随着方法的调用而存在 随着方法的调用完毕而消亡
内存分配
程序运行时 操作系统会分配内存空间 主要分为三块
栈内存:直接存放基本类型的局部变量 和 引用类型的地址 栈内存空间比较小 存取速度相对较快 先进后出原则
堆内存;存放引用类型的实际数据部分(new 出来的实体) 堆内存空间较大 存取速度较慢
方法区:静态区 串池 方法区中有一块区域叫做串池 用来存储字符串常量 静态区 存的是被static静态修饰的成员
构造方法定义:用来创建对象的 并且可以给对象的属性进行初始化赋值
语法格式:[访问权限修饰符] 类名(形参列表){
方法体
}
特点:
.方法名和类名 全相同(大小写都要一模一样)
.没有返回值类型 连void都没有
.没有具体的返回值 return return; 可以写 但是不能有任何返回值 默认是不写的 完全不推荐写
.在创建对象的时候 系统会帮我们调用构造方法 构造方法 不用 对象的引用.方法名 调用
构造方法与普通方法的区别
.构造方法在创建对象的过程中调用 普通方法只能手动调用
.构造方法没有返回值类型 连void都没有
普通方法返回值是什么 返回值类型就是什么 要么就是void
.构造方法的方法名必须和类名一致 普通方法自己写
.构造方法在创建对象过程中就会执行 构造方法只在创建时执行次 普通方法在调用的时候执行可以执行若干次
.系统会默认为我们提供一个无参构造 普通方法自己写
面向对象的四大特征:封装 继承 多态 抽象
封装: 广义上类、方法、包的定义本身是一种封 狭义上 在设计一个类的时候,将所有的属性设置为私有的,并对各个私有的属性设置相应的方法
封装的好处:隐藏实现细节 提供公共的方法,提高安全性
封装的原则:将不需要对外提供的内容封装起来,把属性隐藏,提供公共方法进行访问
private关键字:私有,是一个权限修饰符,可以修饰成员变量和成员方法 被其修饰的成员,只能在本类中使用
封装的步骤:把成员变量用private修饰,提供相应的方法
this.关键字
.调用本类中的成员方法
.访问本类的成员变量
.调用本类的构造方法
.this()不能使用在普通方法里 必须在构造方法的第一句
static关键字
可以用来修饰共有的属性,行为
与类相关,和对象无关,随着类的加载而加载
被类的所有对象共享
多了一种调用方式,可以通过类名.成员名调用
方法区:类信息被存储在一个称之为方法取空间中,类信息就是由类加载器在类加载时从文件中提取
静态和非静态的区别:
所属不同:前者属于类,后者属于对象
内存位置不同:前者存在方法取得静态区中。后存在堆内存中
内存中出现得时间不同:前者随着类的加载而加载,消亡而消亡
后者随着对象的创建而存在
语法:
.修饰成员 (成员变量 / 成员方法)
.修饰成员变量的时候
[访问权限修饰符] static 类型 属性名;
.修饰成员方法的时候
访问权限修饰符] static 返回值类型 方法名(参数列表){
方法体
}
静态修饰方法:被静态修饰的方法 为静态方法
.只能直接访问 静态成员 包括成员变量和成员方法
不能直接访问 非静态成员 包括成员变量和成员方法 必须创建该类对象 才能调用非静态成员
因为静态优先于对象存在 在静态方法加载进内存时 非静态的还没进入内存中
.在静态方法中 没有this/super 关键字
非静态方法:可以访问静态成员 也可以访问非静态成员
总结:静态虽好 不能乱用
利:将对象共享的数据 进行单独存储 节省内存 可以直接用类名.调用
弊:生命周期过长 访问出现局限性 静态只能直接访问静态
main方法梳理:
public static void main(String[] args){
}
主函数 是一个特殊的函数 可以被jvm直接调用 作为程序的入口public 最大权限
static 静态的 在当前方法中会创建对象 需要在创建对象之前
先将main方法加载进内存
void 不确定的返回值 jvm不需要这个返回值
main 一个通用的名称 不是关键字 jvm会识别它
String[] 传入 存储String类型数据的数组
args 参数列表 名 整个main方法中 只有这个能随便写
代码块:
静态代码块 , 局部代码块 , 动态代码块 以{}包裹起来的代码 被称为一个代码块
局部代码块:声明在方法中的代码块 执行时机与声明的位置相关
静态代码块:使用static关键字修饰的代码块 在类加载时执行 并且 只执行一次在类中 方法外定义
格式:
static{
执行内容
}用于给类中的数据进行初始化 一般用于加载驱动 jdbc驱动
动态代码块:又称为构造代码块 声明在类中的代码块 在创建对象是执行一次 每创建一个对象 就会执行一次动态代码块
在类中 方法外定义
格式:{
执行内容
}
执行顺序: 静态代码块>动态代码块>构造方法
继承
定义:继承 就是让类与类之间产生关系-->父子关系
格式:class 类名1 extends 类名2{
}
类名1 继承于 类名2
继承的好处和弊端:
好处:1.提高了代码的复用性
2.提高了代码的维护性
3.让类与类之间产生了关系 是多态的前提
弊端:1.类的耦合性增强了
java中类的继承特点:
.java中类只支持单继承 不支持多继承
.java支持多层继承(继承体系)
.一个父类 可以有多个子类
注意事项:1.不能因为部分共性的内容 而盲目继承
2.子类只能继承父类非私有的成员(成员变量 成员方法)
3.父类的构造方法 不能被子类继承 但是可以通过super()进行调用
继承中成员之间的关系
1.成员变量
同名的变量 如果子类中有和父类同名的成员变量 调用子类自己的(开发中没有这么写的)
不同名的变量 如果子类和父类没有同名的成员变量 this 代表的是当前对象的引用 既可以调用本类的 也可以调用从父类继承过来的成员
super 代表的父类的引用 只可以调用父类的成员
2.成员方法
同名的方法 当子类出现和父类一模一样的方法时 子类对象调用该方法 会运行子类中的方法 如同 父类中的同名方法 被覆盖了一样 这种情况 叫做方法的另一个特征 重写Override
注意事项:
1.父类中私有的方法 不能重写 因为根本无法被继承
2.子类重写父类的方法时 访问权限修饰符不能更低
public > 默认 > private
Override和Overload的区别?
重写:有父子继承关系 方法声明一模一样
重载:在同一个类中 方法名相同 参数列表不同 与返回值无关
不同名的方法子类对象可以直接调用不同名的方法 但是父类私有的 子类不能调用
3.构造方法 因为子类会继承父类中的数据 可能还会使用父类中的数据 所以 创建子类对象之前 先完成父类数据的初始化
调用父类的构造方法 创建子类对象会调用父类构造方法 但是不会创建父类对象 只是调用父类构造方法 完成初始化父类成员的功能
子类 z = new 子类();
调用子类的构造方法
先执行了父类的构造 初始化父类非静态属性 声明普通方法
然后执行了创建子类对象 初始化子类非静态属性
声明普通方法
在堆内存中 你能看到的 只有一个子类对象 但是在子类对象的空间里面 隐含着从父类继承过来的属性和方法 想调用父类的构造方法 可以使用super()来调用
默认情况下 子类的无参构造方法第一句隐含了super()
super关键字
总结: this关键字代表当前对象的引用 谁调用我 我就代表谁
super关键字代表父类的引用
this和super的区别:
1.调用成员方法:this.成员方法 可以调用本类的 也可以调用从父类继承来的 super.成员方法 只能继承自父类的
2.调用成员变量: this.成员变量 可以调用本类的 也可以调用从父类继承来的 super.成员变量 只能继承自父类的
3.调用构造方法 this()调用本类构造 super()调用父类构造
每一个构造方法第一句默认都是super() Object类是最顶层的父类 是所有类的根类
final关键字 最终 最后
继承的出现 让类与类之间产生了关系 打破了类的封装性
final关键字 修饰类 被它修饰的类不能被继承 保证了类的封装性final关键字的特点:
final关键字 可以修饰 类 / 方法 / 变量(成员变量和局部变量)
final修饰类:类不能被继承
final修饰方法:方法不能被重写(覆盖)
final修饰变量:包括成员变量和局部变量 被final修饰的变量 就变成了常量 只能被赋值一次 如果是一个单词 所有字母都大写 NUM 如果是多个单词 每个单词都大写 中间用下划线分割 STUDENT_NUMBER
final修饰的变量 一般会和 public static 一起使用 ---> 全局静态常量
private修饰符 和 final修饰符的区别
private 是权限修饰符可以修饰 成员(成员变量和成员方法) 被私有修饰的成员将不能被继承
final 是修饰符可以修饰 类/成员/局部变量 被final修饰的类不能被继承 方法不能被重写 变量是常量
.抽象
概念:当编写一个类的时候 常常会定义一些方法 这些方法用以描述该类的行为 这些方法都有具体的方法体 但是在某种特殊情况下 某个父类只是知道应该包含什么方法 却不知道该方法是如何实现的 那么我们可以提供抽象方法 并将类声明为抽象类
- abstract 抽象
语法:
抽象类
[访问权限修饰符] abstract class 类名{
抽象方法
普通属性
普通方法
}
抽象方法
[访问权限修饰符] abstract 返回值类型 方法名(参数列表)
抽象方法和抽象类
抽象类的特点:*****
.抽象方法一定在抽象类中
.抽象方法 和 抽象类 都是必须用abstract修饰
.抽象类有构造方法 但是不可以用new 创建对象 因为可能会调用抽象方法 但是抽象方法没有方法体 调用没意义
.抽象类中的抽象方法要被使用 必须由子类重写其所有的抽象方法
建立子类对象 去调用 如果只重写了部分抽象方法 那么子类也是抽象类
.抽象类中可以包含抽象方法 也可以包含非抽象方法 当一个方法被抽象修饰后 他所在的类必须是抽象类 抽象类中可以不定义抽象方法 如果一个抽象类中没有抽象方法 那么定义这个类的目的 就只有一个 就是不让该类创建对象
抽象的好处
1.强制子类重写抽象方法
2.父类定义功能 功能体由子类完成 当有父类的时候 可能还没有子类的 但是我知道 我的子类都要去做某件事 那么声明方法 但是不给方法的具体实现方式 由子类实现
总结:
private static final abstract 能否一起使用 修饰方法
abstract可不可以 与 final private static共存
abstract 和 static 不能一起使用 因为static修饰的成员方法 多了一种调用方式 类名.调用
静态与类相关 与对象无关 调用抽象方法 没意义 所以不行
abstract 和 final 不能一起使用
final修饰不能被重写
abstract 要求子类必须重写
abstract 和 private 不能一起使用
private不能被继承 何谈被重写
static final abstract的区别
static:属性 共有的 类名直接调用 方法 共有的 类名直接调用
不能用this/super 只能直接调用静态 通过创建对象 可以调用非静态
代码块随着类的加载而加载 只执行一次
final:属性/局部变量 是常量 方法 不能被重写 类 不能被继承abstract:方法 抽象方法 只能放在抽象 想要使用 必须在子类中重写 构造方法 不能被abstract修饰 static方法 不能被abstract修饰
类 抽象类 不能被实例化 但是有构造方法 抽象类中 可以有抽象方法 和 非抽象方法