目录
一、类和对象的基本概念
1.概述
类是现实世界中一类具有共同属性和行为的事物的抽象。
可以认为类是一种数据结构,用属性来表示一类事物的共同特征,方法来表示这类事物的行为.。类是抽象的,对象是具体的。eg.游戏是抽象的,光遇是具体的。
2.类定义
修饰符 class 类名{
// 此处的修饰符仅可为 public或者默认修饰符
属性 ...
行为 ...}
3.创建对象
通过new关键字进行对象的创建、
eg.
public class DemoTest{
public static void main(String []args){
Demo demo = new Demo();
// new Demo() 创建对象并返回在堆中分配的地址
// Demo demo 接收返回的地址
// 然后就可以通过饮用变量demo 访问在堆中的数据
}
}
class Demo{
}
二、类的基本组成
1.成员变量
1)访问修饰符:用来控制访问权限的标识符
同类中 | 同一个包下 | 不同包下的子类 | 不同包下非子类 | |
public | ✔️ | ✔️ | ✔️ | ✔️ |
protected | ✔️ | ✔️ | ✔️ | ❌ |
默认修饰符(什么都不写) | ✔️ | ✔️ | ❌ | ❌ |
private | ✔️ | ❌ | ❌ | ❌ |
2)成员变量和局部变量
成员变量定义在类中方法外
局部变量定义在类中方法内或代码块内
a.成员变量不赋值有初始值,局部变量不赋值无初始值,需先赋值后使用。
b.成员变量可以用访问修饰符修饰,局部变量不能使用访问修饰符修饰。
c.成员变量随着对象的创建而创建,随着对象的销毁而销毁。局部变量随着方法的调用而创建,随着方法调用结束而销毁。
d.局部变量可以和成员变量重名,在访问时遵循就近原则
eg.
3)类变量
此类的所有对象共享的变量,定义格式为
定义格式
static 访问修饰符 数据类型 变量名;
或
访问修饰符 static 数据类型 变量名;
调用
类名.变量名
对象名.变量名
2.成员方法
1)成员方法的定义和调用
访问修饰符 返回值类型 变量名(参数列表){
方法体}
调用:
对象名.方法名()
注意:先创建对象,后调用方法
2) 类方法的定义和调用
访问修饰符 static 返回值类型 方法名(参数列表){
方法体}
调用:
类名.方法名()
对象名.方法名()
3)方法重载和重写
方法重载:在同一个类中多个重名但参数列表不同的方法
方法重写:发生在父子类中,子类对父类方法实现的改写。
方法名 | 参数列表 | 访问修饰符 | 返回值、抛出的异常 | |
重载 | 必须相同 | 不同 | 无要求 | 无要求 |
重写 | 必须相同 | 相同 | 不能缩小父类的访问权限 | 是父类返回值(抛出的异常)的子类或者相同 |
3.构造器
1)无参构造器
访问修饰符 类名(){
方法体;}
// 创建对象时,由系统调用
2)有参构造
访问修饰符 类名(参数列表){
方法体}
3)this关键字
用于表示当前对象的引用
class A{
String name;
int age;
// 无参构造器
A(){
this(" ", 17);
// 可以使用this(参数列表)访问本类的其他构造器,使用必须放在构造器的第一行
}
A(int age, String name){
this.name = name;
this.age = age;
// 此处,局部变量name和age与成员变量名相同,如果想为成员变量赋值,可以使用this表示当前对象引用
}
}
4)IDEA快捷键Alt+Insert
5)注意事项
a.不提供构造器,系统提供默认的无参构造方法。
b.一旦提供了有参构造方法,就会覆盖系统提供的无参构造器,需要手动创建无参构造器。
4.代码块
1)普通代码块
class A {
private int age;
//代码块(用“{ 表示}”)
{
//作用,对构造器的补充,提取构造器中重复的语句
// 在其中也可以使用其他语句,如一些判断、赋值语句
}
A(){
...-->一些初始化的语句
}
A(int age){
...-->一些初始化的语句
}
}
2)静态代码块
class A {
private int age;
//静态代码代码块(用“{ 表示}”)
stati{
//作用,在创建对象前进行的一些操作,如类变量的赋值。
//
}
A(){
...-->一些初始化的语句
}
A(int age){
...-->一些初始化的语句
}
}
5.内部类
1)局部内部类
2)匿名内部类
3)成员内部类
4)静态内部类
三.面向对象三大特征
1.封装
1)封装思想
属性私有化,拒绝直接访问,提供公共的接口访问数据。
2)常规实现方式
class Demo{
// 1.私有化属性
private double salary;
// 2.提供访问数据的方式
public double getSalary()(
....)
// 3.提供修改数据的方式
public void setSalary(){
}
}
3)作用
a.隐藏实现细节,方便调用者使用,只需要通过外部接口调用即可,不必关注内部变化。如电视机,我们仅需要通过它提供的按钮去使用服务,而不必关注它是如何工作的。
b.增加数据校验,提高安全性,在提供放入公共接口中,可以加入一些业务逻辑进行判断。
2.继承
1)继承思想
继承是子类继承父类的特征和行为(只能访问非private修饰的属性和方法),使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
2)实现方式
extends关键字
3)作用
提高代码的复用性、可维护性以及扩展性
4)缺点
降低代码的灵活性。子类必须拥有父类的属性和方法,让子类自由的世界中多了些约束;
增强了耦合性。当父类的常量、变量和方法被修改时,需要考虑子类的修改。
4)注意事项
a.在创建子类对象时,会调用父类的无参构造器完成父类初始化,如果父类没有无参构造器,则需要通过super(参数列表)显式的调用父类的其他构造器。如果父类没有无参构造,子类也没有显式地指定其他构造器,那么编译不通过。
b.子类通过继承获得父类的属性和方法,但只能访问父类的非私有属性和方法。
c.java是单继承机制。
d.访问属性和方法规则是,先在本类中查找,没有的才会往上寻找。
eg.
public class GirlFriendTest {
public static void main(String[] args) {
B b = new B();
System.out.println(b.num1+"\n"+b.num2);
// 运行结果为: 5
10
}
}
class A {
int num1 = 9;
int num2 = 10;
}
class B extends A{
int num1 = 5;
}
3.多态
1)分类
编译时多态:重载(方法名相同,通过不同参数运行不同实现的方法)
运行时多态
2)编译类型和运行类型
编译类型:定义时的数据类型
运行类型:运行时指向的数据类型决定
eg.
public class Test{
public static void main(String [] args){
Father father = new son();
// 编译看左边,运行看右边
}}
class Father{}
class Son extends Father{}
3)向上转型和向下转型
向上转型:父类引用指向子类对象,如上图 Father father = new Son();
向下转型:子类引用指向父类对象
eg.
public class Test{
public static void main(String [] args){
Father father = new son();
Son son = (Son)father;
// 父类对象的真实类型为子类
}}
class Father{}
class Son extends Father{}
4)动态绑定机制
Java中,对象调用的方法与其运行类型绑定
5)运行时多态
a.条件:继承、向上转型、方法重写
b.具体表现:运行时调用的方法与其运行类型绑定
6)注意事项
a.对象调用方法时存在动态绑定机制,属性则没有
b.上转型对象能访问父类中的属性和方法(遵循访问权限),不能访问子类特有的属性和方法
c.可以使用insatnceof来判断对象的运行时类型。