Java面向对象
//变量的作用域
类级变量>成员级变量>方法级变量>块级变量
面向编程:我们在解决问题中,注重的是解决问题的每一个为步骤和过程。
面向对象:注重的是在问题中,涉及到哪些对象,以及对象之间有哪些关系。
| 核心思想 | 缺点 | 算法 |
面向编程 | 自顶向下,逐步求精,也就是把功能分解。
涉及数据结构
编写基础代码,基于数据结构操作 | 一旦数据结构发生修改,必须要修改操作的代码
可重用性差
可维护性,维护的成本高 | 程序 = 数据结构+算法 |
|
| 绝对的优点 |
|
面向对象 | 分解数据
数据,和操作数据是一个整体 | 数据修改,只涉及对该数据的操作(封装)。
可重用性强(继承)
可维护性好,维护的成本低 | 程序 = 对象 +消息
|
万事万物皆对象,对象是由静态的属性和动态的方法来组成的。
类:是一组具有相同属性和行为的对象的抽象
消息:对象之间的通信和响应
·类和对象
抽象:
提取事物的本质,共性的属性和方法,忽略某些不必要的细节和个性的差异。
封装:
存在一个边界,边界之内的细节隐藏起来。只留下对外接口的接口(如:笔记本、手机、饮水机)。
为什么使用封装:1.易用简单 2.安全3.容易维护
继承:
允许后代直接使用先辈的所有属性和行为。
为什么使用继承:更好的实现了代码的重用。
多态:
不同的对象,接收到相同的消息,产生的响应不同。
总结:面向对象是一种很自然、朴素的方法,来源于生活。
构造函数:
构造函数是在对象实例化的时候自动被系统调用,该函数名必须是独一无二的。对于一个类来说,是将类名作为函数名,
构造函数不需要程序员去定义返回值,他是系统自动决定的,void也不行。
Static 静态:静态代码块是在加载类的时候自动被执行,早于构造函数,静态的方法,面向的是整个类,不是某个对象,所以没有this , 并且只能使用类名来调用,不能使用实例化对象去调用。
垃圾回收机制:
类的组成:成员变量和成员方法
面向对象封装的体现
多态的体现 :重写、重载等。
引用:Point p = new Point(); 的含义是首先实例化一个对象(new Point()),然后定义一个引用,p指向这个实例,p = p1; 并不是将实p1赋值给实例p ,而是改变了引用的关系。
赋值兼容性规则:凡是需要使用父类对象的地方,都可以使用其公有子类去代替。
Final 修饰的类不能被继承 ,final修饰的变量不能被修改(也就是常量),Final 修饰的方法不能被重写。
继承实现了面向对象的原则:write once,only once(编写一次、且编写一次)
继承的注意事项:
调用父类的构造方法的语句(super语句)必须是构造方法中的第一条语句。
在子类中可以通过super();调用父类中被子类覆写的方法。
因为创建对象的时候,需要先创建父类对象,再创建子类对象。
注意:创建对象时,先创建父类对象,在创建子类对象。如果没有显示调用父类的构造方法,将自动调用父类的无参构造方法。
栈内存与堆内存:
·抽象类
抽象方法:只有声明,没有实现。abstract修饰抽象方法
抽象类:就是含有抽象方法的类。
抽象类不能被实例化,也就是不能new,它的作用只能作为父类被继承,作用是:对后代进行规则,即凡是它的后代,必须实现它为完成的方法。
比如说,形状肯定有计算周长和面积的方法,但是具体如何计算的,却无法描述。三角形有三角形计算的方法,圆有圆计算的方法,所以在形状这个类只能声明这个方法,但是不能实现。(有抽象方法的类就叫抽象类)
为什么需要使用抽象类?
在现实生活中,有些我们明明知道是有某些方法的,但是具体这些方法是怎么去做的好像又无法说清楚。比如手机、电报、固定电话等都是通讯工具,而通讯工具应该具有向外传送消息的方法,但是却无法说明具体怎么发,而手机、电报等我们可以说清楚它们是怎么发送消息的。
由于抽象类中包含有未实现的方法,所以抽象是无法去实例化对象(new),那么它的作用是什么呢,它可以对它们的后代进行规划和约束,后代必须去按照他的要求去实现,但具体怎么实现由后代去决定。
接口:
接口的所有方法都是抽象方法:所以在声明方法时,关键词abstract写不写无所谓了。接口定义的关键词是interface、抽象类是class。抽象类是用来继承(extends)的,接口是用来实现(implements)的。
匿名内部类
为什么要使用匿名内部类
先看看如果不使用匿名内部类的情形;
(1)定义接口(如果已经有则跳过)
public interface Shape {
public String getName();
public double area();
public double perimeter();
}
(2)实现了这个接口
(3)定义这个类对象并使用
public class Test {
public static void main(String[] args) {
Shape square = new Square(5);
Shape shape = square;
print(shape);
}
public static void print(Shape shape){
System.out.println(shape.getName()+"的周长是 "+shape.perimeter()+"\n面积是"+shape.area());
}
}
那么如果使用内部类呢?
(1)定义接口(与上一种情况一样)
(2)定义匿名内部类,并实现接口(实际上就是将上一种情形的第2、3步合并了)。
匿名内部类显然简化了流程,但是也使得使用者理解更困难了,代码的层次不是太清晰。