面向对象编程
什么是面向对象
面向对象 & 面向过程
面向过程:
步骤清晰简单,第一步做什么,第二部做什么…
面向过程适合处理一些较为简单的问题。
面向对象:
物以类聚,适合开发大型软件
整体实现,管理整个软件的开发
本质:以类的方式组织代码,以对象的组织封装数据
总结
1.都是解决问题的思维方式,都是代码组织的方式
2.解决简单问题可以使用面向对象
3.解决复杂问题:宏观上使用面向对象把握,微观处理上仍然是面向过程
方法回顾和加深
方法的定义
- 访问修饰符
- 返回值类型
- break和return的区别
- 方法名:注意规范就OK,见名知意
- 参数列表:(参数类型 参数名)…
- 异常抛出
方法的调用:递归
- 静态方法
- 非静态方法
如果没有方法上没有static,需要实例化这个类才能调用这个方法
-
形参和实参
-
值传递和引用传递
public class Demo { public static void main(String[] args){ int a = 1; System.out.println(a); //1 Demo.change(a); System.out.println(a); //1 } public static void change(int a){ a = 10; } }
public class Demo { public static void main(String[] args){ Person p = new Person; System.out.println(p.name); //null Demo.change(p); System.out.println(p); //张三 } public static void change(Person p){ // person是一个对象:指向的是Person p = new Person(); //这是一个具体的对象,可以改变属性 p.name = "张三"; } } class Person{ String name; // null }
-
this关键字
对象的创建内存分析
Java虚拟机的内存可以分为三个区域:栈stack
,堆heap
,方法区method area
(属于堆)
栈的特点如下:
1.栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量,操作数,方法出口等)
2.jvm为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数,局部变量等)
3.栈属于线程私有,不能实现线程间的共享!
4.栈的存储特性是“先进后出,后进先出”
5.栈是由系统自动分配,速度快!栈是一个连续的内存空间!
堆的特点如下:
1.堆用于存储创建好的对象和数组(数组也是对象)
2.jvm只有一个堆,被所有线程共享
3.堆是一个不连续的内存空间,分配灵活,速度慢
方法区(静态区)的特点如下:
1.jvm只有一个方法区,被所有线程共享。
2.方法区实际也是堆,只是用于存储类,常量相关的信息。
3.用来存放程序中永远是不变或唯一的内容(类信息,静态变量,字符串常量等)
4.JVM 的内存布局和运行原理
面向对象的三大特征
封装(数据的隐藏)
1.使用 private
关键字来修饰成员变量。
2.使用public
修饰getter和setter方法。
继承:Java中类只有单继承,没有多继承!
继承:就是子类继承父类的属性和行为,使得子类对象可以直接具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。
extends
的意思是“扩展”。子类是父类的扩展。
在Java中,所有的类都默认继承object
super:访问父类的属性和方法
public class Person{
protected String name = "zhangsan";
}
public class Student extends Person{
private String name = "lisi"
public void test(String name){
System.out.println(name); //wangwu
System.out.println(this.name); //lisi
System.out.println(super.name); //zhangsan
}
}
public class Demo {
public static void main(String[] args){
Student s = new Student();
s.test("wangwu ");
}
}
方法同理
**super()**
调用父类的构造方法,必须在构造方法的第一个
super必须只能出现在子类的方法或者构造方法中
super和this不能同时调用构造方法
Vs this
:
-
代表的对象不同:
this():本身调用者这个对象
super():代表父类对象的应用
-
前提
this():没有继承也能使用
super():只有在继承条件下使用
-
构造方法:
this():本类的构造
super():父类的构造
方法重写:需要有继承关系,子类重写父类的方法!
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大
重写,子类和父类的方法名必须一致,方法体不同!
为什么需要重写:
1.父类的功能,子类不一定需要,或者不一定满足
多态
多态是出现在继承或者实现关系中的。
多态体现的格式:
父类类型 变量名 = new 子类/实现类构造器;
变量名.方法名();
多态的前提:有继承关系,子类对象是可以赋值给父类类型的变量。例如Animal是一个动物类型,而Cat是一个猫类型。Cat继承了Animal,Cat对象也是Animal类型,自然可以赋值给父类类型的变量。
多态存在的条件:
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
抽象类
abstract
修饰符可以用来修饰方法也可以修饰类
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的
接口
接口是一种规范,定义的是一种规则
OOP的精髓,是对对象的抽象,最能体现这一点就是接口
内部类和OOP实战
内部类就是在一个类的内部再定义一个类
-
成员内部类
public class Outer { private int id; public void out(){ System.out.println("这是外部类的方法"); } public class Inner{ public void in(){ System.out.println("这是内部类的方法"); } } }
-
静态内部类
-
局部内部类
-
匿名内部类
public class Test { public static void main(String[] args) { //没有名字初始化类,不用讲实例保存到变量中 new Apple().eat(); UserService userService = new UserService() { public void hello() { } }; } } class Apple{ public void eat(){ System.out.println("1"); } } interface UserService{ void hello(); }