面向对象编程
面向对象 & 面向过程
- 面向过程
- 步骤清晰简单,第一步做什么,第二步做什么...
- 适合处理一些较为简单的问题
- 面向对象
- 分类的思维模式,思考问题首先会解决问题需要那些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
- 适合处理复杂的问题,适合处理需要多人协作的问题!
- 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
面向对象
- 本质:以类的方式组织代码,以对象的组织(封装)数据
- 抽象
- 三大特性
- 封装
- 继承
- 多态
方法
- 调用
- 静态方法 static
- 和类一起加载的
- 可直接调用
- 非静态方法
- 类实例化后才存在
- 需要new
- 静态方法 static
类与对象的关系
- 类
- 一种抽象的数据类型,是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物
构造器
- 类中的构造器也成为构造方法,是在进行创建对象的时候必须要调用的(若类中没有写,编译器在编译时会自动创建)。并且构造器有一下两个特点:
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
- 当类中定义了一个有参构造时,无参构造必须显式定义
- new本质就是调用构造器
创建对象内存分析

封装
- 数据的隐藏
- 通常应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
- 优点
- 提高程序安全性,保护数据
- 隐藏代码的实现细节
- 统一结构
- 系统可维护性增加
继承
- 概念
- 本质是对某一批类的抽象,从而实现对现实世界更好的建模
- JAVA只有单继承,没有多继承
- 继承时类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等
- 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
- 在Java中所有的类都默认继承object类
- Super
- 调用父类构造方法,必须在构造方法的第一个
- 必须只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法
- 方法重写
- 子类对父类中有public关键词且不是静态的方法可进行重写
- 注意点
- 方法名必须相同
- 参数列表必须相同
- 修饰符范围可以扩大不能缩小
- 抛出的异常:范围可以被缩小但不能扩大
- 为什么要重写?
- 父类的功能:子类不需要,或者不一定满足!
- eclipse快捷方式:source --> Oveeride/Implements Methods
多态
-
定义
- 即同一方法可以根据发送对象的不同而采用多种不同的行为方式
- 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
-
多态存在的条件
- 有继承关系
- 子类重写父类的方法
- 父类引用指向子类对象
-
注意点
- 多态是方法的多态,属性没有多态
- 父类和子类有联系
-
实例
//父类 public class Person { public void run() { System.out.println("run"); } } //子类 public class Student extends Person{ @Override public void run() { // TODO Auto-generated method stub super.run(); } public void eat() { System.out.println("eat"); } } //测试类 public class hello { public static void main (String[] args) { Student student = new Student(); Person person = new Student();//父类的引用指向子类 Object object = new Student(); person.run(); //指向子类,可以调用父类的方法,但是方法被重写时只能调用到子类的方法,且不能调用子类独有的方法 student.run();//能调用的方法都是自己的或者继承父类的 } } -
Instanced(类型转换)
//instanceof判断是否满足父子关系 Object object = new Student(); System.out.println(object instanceof Student);//true System.out.println(object instanceof Person);//true System.out.println(object instanceof Object);//true //从低到高自动转换 Person person = new Student();//student将这个对象转换为student类型,我们就可以使用student类型的方法了 //强制转换 高到低 Student student = (student)obj; /* 1、父类引用指向子类的对象 2、把子类转换为父类,向上转型 3、把父类转换为子类,向下转型;强制转换 优点:方便方法调用,减少重复的代码,提高利用率 */ -
static
public class Person { { System.out.println("匿名代码块"); } static { System.out.println("静态代码块"); } public Person() { System.out.println("构造器"); } public static void main(String[] args) { Person person1 = new Person(); System.out.println("==========="); Person person2 = new Person(); } } /* 结果如下: 静态代码块 匿名代码块 构造器 =========== 匿名代码块 构造器 说明:加载顺序——静态代码块(只执行一次)➡️匿名代码块➡️构造器 *///静态导入包 import static java.lang.Math.random; public class Person { public static void main(String[] args) { System.out.println(random());//可以直接调用 } }
抽象类
-
概念
- abstract修饰符。修饰方法就是抽象方法,修饰类就是抽象类
-
注意点
- 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类
- 抽象类不能用new关键字来创建对象,它是用来让子类继承的
- 抽象方法只有方法的声明,没有方法的实现,它是用来让子类实现的
- 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类
-
缺点
- 由于摆脱不了extends的约束,只能单继承
-
拓展
-
抽象类有构造方法吗?
-
抽象类可以有构造方法,构造方法不可继承,但是可以供子类用super()或者super(参数)调用。
-
如果在父类中(就是你的抽象类)中显示的写了有参数的构造函数,在子类继承是就必须写一个构造函数来调用父类的构造函数。
abstract class Person { //定义一个抽象类,必须被继承 Person(int i) { } } public class Student extends Person { Student() { super(int i)://必须显示的调用父类构造方法//super代表父类对象 } } //来源 https://www.iteye.com/problems/67636
-
-
抽象类存在的意义
- 1.可以把同一种类型的对象共性抽取出来后封装成抽象类,子类通过继承该抽象类达到代码编写简洁,易于维护的目的。
- 2.通过抽象类定义一系列规范,继承该抽象类的子类必须实现相应的抽象方法,使得该子类具有相应的规范性。
- 3.实现多态。
-
接口
-
就是规范,约束和实现的分离,面向接口编程
-
接口的本质是契约
-
关键字 interface
-
实现
//第一个接口 //interface 定义的关键字 接口都需要实现类 public interface Person { //接口不能被实例化,接口中没有构造方法 //默认是final public static 的常量 int AGE = 99; //接口中的所有定义其实都是抽象的public abstract 默认的不需要自己加 void run(String name); void walk(String name); void dive(String name); } //第二个接口 public interface hello { void sayHello (String name); } //一个类可以实现一个接口 //实现类接口的类就要重写接口的方法 //通过接口实现多继承 public class Student implements Person,hello{ @Override public void run(String name) { // TODO Auto-generated method stub } @Override public void walk(String name) { // TODO Auto-generated method stub } @Override public void dive(String name) { // TODO Auto-generated method stub } @Override public void sayHello(String name) { // TODO Auto-generated method stub } }
内部类
-
内部类
public class Student{ private int id = 99; public void stuName() { System.out.println("这里是stuName"); } //内部类 public class xiaoMing{ public void Name() { System.out.println("这里是小明"); } //调用外部内的方法 public void xiaoMingName() { stuName(); } //获得外部类的私有属性 public void getStuId() { System.out.println(id); } } } //一个java类中可以有多个class类,但是只能有一个public class class ZhangSan{ } //测试类 public interface hello { public static void main(String[] args) { //先实例化外部内 Student student = new Student(); //通过外部类来实例化内部类 Student.xiaoMing xMing = student.new xiaoMing(); //调用内部内自己的方法 xMing.Name(); //内部类不能直接调用外部类的方法,如 xMing.stuName(),这样是不允许的。但是可以通过内部类的方法调用外部类的方法 xMing.xiaoMingName(); xMing.getStuId(); } } /* 输出: 这里是小明 这里是stuName 99 */ -
静态内部类
public class Student{ private int id = 99; public void stuName() { System.out.println("这里是stuName"); } //内部类 public static class xiaoMing{ public void Name() { System.out.println("这里是小明"); } //获得外部类的私有属性 public void getStuId() { System.out.println(id);//报错 由于内部类是static,会先实例化,在id之前,所以无法调用 } } } -
局部内部类
public class Student{ public void method() { class Inner{ } } } -
匿名内部类
public class Student{ public static void main(String[] args) { //没有名字初始化类,不用将实例保存到变量中 new xiaoMing().name(); People person1 = new People() { @Override public void run() { // TODO Auto-generated method stub } }; } } class xiaoMing{ public void name() { System.out.println("xiaoMing"); } } interface People{ void run(); }

浙公网安备 33010602011771号