面向对象的本质是以类的方式组织代码,以对象的组织(封装)数据。
面向对象有三大特征:封装,继承,多态。
类是抽象的数据类型,是对某一事物的整体描述。
对象是抽象概念的具体实例,例如张三是人的具体。
具体理解,还需要在代码中去理解。
这里尽量用简单且少的代码去理解对象与类;
要想有对象,就得现有类,对象是类的实例化。
使用new关键字创建对象,
在实践中要注意,在一个项目应该只存在一个main方法!!
Student student = new Student();//实例化一个student对象
//使用new时,会分配空间,并进行对象的初始化,以及对构造器的调用。
具体使用
首先定义一个类
class Demo {
public Demo() {
System.out.println("构造方法被调用了");
}
}
定义完成后,创建一个Demo对象。当创建对象时,构造方法被调用。
public class Demo2 {
public static void main(String[] args) {
Demo d = new Demo();
}
}
//新创建了一个Demo类型的d,这就是将类实例化
构造器
在上一个代码中,我们便使用了构造器。
什么是构造器,一个类即使什么也不写,也会存在一个默认方法,即构造器;
实际上,在每一个类中,都会存在一个我们看不见的,与类名同名的方法,当我们实例化类的时候,该方法就会被调用
public class A{
public A(){
//这就是一个构造方法。
}
}
构造器特点:
- 与类名相同
- 无返回类型,也不能写void
- 使用new的本质是调用构造器
- 构造器一般用来初始化值
- 如果定义了有参构造,必须再定义无参构造
- 数字:0,0.0;
- char:/u0000
- boolean:false
- 引用:null
- String: null
实际上,String也是引用类型。
面向对象三大特性在我们的Java中的核心思想就是面向对象,面向对象有三大特征:
封装
继承
多态
高内聚,低耦合。
高内聚:类的内部细节由自己完成,不允许外界干涉
低耦合:尽量暴露少的方法供外界使用。
封装一般是对属性的封装,少量的方法封装。
封装的核心是私有
private 变量 //属性私有化
私有属性话后,再提供public的get、set方法
简单来说,封装就是通过private关键字,让被私有化的属性不可以被类外的方法调用,从而实现对数据的管理。
继承的本质是对某一批类的抽象,从而实现对现实世界的建模
extends
类似于子承父业,extends是扩展的意思,子类是父类的扩展。
是类与类之间的关系。
类只有单继承,没有多继承,接口可有由多个接口。
子类会继承父类所有公共的方法属性
修饰符开放等级:
- public,开放等级最高,可以在任何一个类中被调用,不管同包或不同包,
是权限最大的一个修饰符 - protected,受保护的,能在定义它们的类中,同包的类中被调用。如果有不同包的类想调用它们,那么这个类必须是定义它们的类的子类
- default,默认的,默认权限即同包权限,同包权限的元素只能在定义它们的类中,以及同包的类中被调用
- private,私有的,只能在定义它们的类中使用,在其他类中不能调用
所有的类,都默认继承object类,idea中ctrl+H可以查看类的继承
thisthis.属性名,代表调用当前对象的属性。
class Demo {
String name;
public Demo(String name){
this.name = name;
}
}
也就是说,那么代表传入的参数,而this.name代表的是当前类创建的对象的属性。
supper代表父类的引用,用于访问父类的属性,方法,构造器
- 访问父类属性,但不能访问私有的属性。
- super调用父类的构造方法,super必须在子类的构造器中,且是第一行
- 调用时,有祖宗类时,且调用的方法名相同时,遵循就近原则
- super和this不能同时调用构造方法
是一个关键字,表示最终的,不可变的,修饰变量,方法,类
修饰的类无法被继承
修饰的方法,该方法无法被重写。
final修饰的局部变量一旦被赋值,就不能改变。
final修饰的变量只能付一次值
重写都是方法的重写
需要有继承关系,是子类重写父类
- 方法名必须相同
- 参数名必须相同
- 修饰符可以扩大,但是不能缩小。
- 抛出异常,范围可以被缩小 ,但不能扩大。
多态就是同样的方法根据发送对象的不同而采用不同的行为方式
是建立在封装和继承的基础之上的
方法的重载体现了多态。
方法的重写体现多态。
对象的多态时多态的具体体现。
一个对象的编译类型和运行类型可以不一致
A a = new B();//父类的引用指向b类
编译类型在定义时就确定了,运行类型是可以改变的
A a = new B();//父类的引用指向b类,a类型已经确定
a = new C();//但是可以改变运行类型,C为A的子类
父类和子类有联系,类型转换异常:ClassCastException
instanceof
用来判断是否是继承关系,返回为一个布尔类型。
父类 instanceof 子类。
父类引用指向子对象,调用子类的方法,需要进行类型转化,即将父类引用转化为子类型
子类转父类,可能会丢失一些子类方法
static修饰符详解
static修饰方法时,静态的方法可以直接用类名.方法名来调用,而非静态方法需要实例化对象之后才能使用。
静态方法中可以调用静态方法,非静态当中可以调用静态方法,但是静态方法中不能调用非静态方法。
静态代码块
static{
//静态代码块
}
{
//匿名代码块
}
//匿名代码块跟静态代码块在创建对象的时候就会加载进去
static类型的变量方法在程序执行时会加载到内存里
拓展
静态导入包,之后可以调用类里面的方法。
finll修饰的类,不能被继承
abstract修饰的类,变成抽象类。
接口可以多继承
//抽象方法
public abstract class Action{
public abstract void max(); //只有方法名字,没有方法实现。
}
抽象类的所有方法必须有子类实现
抽象类不能new(无实例化),只能用子类实现,是一个约束。
抽象类中可以有普通方法,但是抽象方法必须在抽象类中。
普通类,只有具体实现。
抽象类:具体实现和抽象方法都有
接口:只有规范,自己无法写方法。(约束和实现分离)关键字interface
接口是面向对象的精髓,接口需要有实现类,通过implement,可以一个实现类有多个接口。
实现类需要重写接口中的方法。
简单来说,就是类里包含另一个类,有点类似于循环的嵌套用法。
public class A{
//这是外部类
public class B{
//这是内部类
}
}
调用时,需要通过外部类来调用内部类
public static class Active{
public static void main(String [] args){
A a = new A(); //创建一个外部类对象
A.B b = a.new B(); //通过外部类指向一个内部类对象
}
}
内部类可以访问到外部类的私有属性,私有方法。
当内部类是静态时无法访问,因为静态是在程序创建时就已经加载完毕。但是外部类也是静态方法时可以访问。
一个文件中只能有一个public class,但可以有多个class。
没有名字的内部类,直接定义,直接调用。
new A().eat();
//使用匿名内部类来调用方法。