5面向对象编程

5面向对象编程
面向对象的三大特性

面向过程和面向对象
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
例如五子棋,面向过程的设计思路就是首先分析问题的步骤:
1、开始游戏,
2、黑子先走,
3、绘制画面,
4、判断输赢,
5、轮到白子,
6、绘制画面,
7、判断输赢,
8、返回步骤2,
9、输出最后结果。
把上面每个步骤用分别的函数来实现,问题就解决了。
而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为:
1、黑白双方,这两方的行为是一模一样的, 棋子 {color // 子的颜色; 落子() {}}
2、棋盘系统,负责绘制画面, 棋盘系统 {绘制画面() {}}
3、规则系统,负责判定诸如犯规、输赢等。 规则系统 {判断输赢() {}}
第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

以方法为单位组织代码、以类为单位组织代码。
对象和类的概念
对象:对象是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
类:类是一个模板,它描述一类对象的行为和状态。
类:class
对象:object、instance。某个类的对象,实际上就是某个类的实例。
类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
类用于描述同一类型的对象的一个抽象的概念,类中定义了这一类对象所应具有的静态和动态的属性。
对象是java程序的核心,在java程序中“万事万物皆对象”。
jdk提供了很多类供编程人员使用,编程人员也可以定义自己的类。
引用类型
java语言中除了基本类型之外的变量类型都称之为引用类型。
java中的对象是通过引用"reference"对其操作的。
类的属性
属性field,或者叫成员变量
属性用于定义该类或该对象包含的数据或者说静态属性。
属性作用范围是整个类体
在定义成员变量时可以对其初始化,如果不对其初始化,java使用默认的值对其初始化。(数值:0,0.0, char:\u0000, boolean:flase, 所有引用类型:null)
属性定义格式:
[修饰符] 属性类型 属性名 = [默认值]
类的方法
面向对象中,整个程序的基本单位是类,方法是从属于类的。
方法定义格式:
[修饰符1 修饰符2 …] 方法返回值类型 方法名(形参列表) {
// n条语句;
}
形式参数:在方法被调用时用于接收外界输入的数据。
实参:调用方法时实际传给方法的数据。
返回值:方法在执行完毕后返还给调用它的环境的数据。
返回值类型:事先约定的返回值的数据类型,如无返回值,必须给出返回值类型void。
java语言中使用下述形式调用方法:对象名.方法名(实参列表)
实参的数目、数据类型和次序必须和所调用方法声明的形参列表匹配。
return 语句终止方法的运行并返回指定类型的数据。
java中方法参数传递是:值传递! https://www.cnblogs.com/nnngu/p/8299724.html
变量的作用域

成员变量如果不赋初值,系统会给予其默认值。
局部变量在使用前必须给其赋值,系统不会给其默认值。
内存分析
栈(自动分配连续的空间,后进先出)。存放:局部变量
堆(不连续)。存放new出来的对象。
方法区(属于堆的一部分)。存放:类的信息(代码)、static变量、常量池(字符串常量)等 。

垃圾回收机制
对象空间的分配:使用new关键字创建对象即可
对象空间的释放:将对象赋值null即可。垃圾回收器将负责回收所有“不可达”对象的内存空间。
要点:
程序员无权调用垃圾回收器。
程序员可以通过System.gc()。通过GC运行,但是java规范并不能保证立即运行。
finalize方法,是java提供给程序员用来释放对象或资源的方法,但是尽量少用。
构造器(构造方法、构造函数)
构造器,constructor
构造器用于构造该类的实例。
格式如下:
[修饰符] 类名 (形参列表) {
// n条语句
}
构造器是一种特殊的方法:
通过new关键字调用
构造器虽然有返回值,但是不能定义返回类型(返回值的类型肯定是本类),不能在构造器里调用return。
如果我们没有定义构造器,系统会自动定义一个无参的构造器。如果已定义则默认无参的构造器不会存在。
构造器的方法名必须和类名一致。
方法的重载(overload)
方法的重载是指一个类中可以定义有相同的名字,但参数不同的多个方法。调用时,会根据不同的参数列表选择对应的方法。
口诀:二同三不同
相同:同一个类,同一个方法名
不同:参数列表不同(类型、个数、顺序不同)
只有返回值不同不构成方法的重载
只有形参的名称不同,不构成方法的重载
与普通方法一样,构造方法也可以重载
static
在类中,用static声明的成员变量为静态成员变量,或者叫做类属性、类变量。
它为该类的公共变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化。
对于该类的所有对象来说,static成员变量只有一份。被该类的所有对象共享。
可以使用“对象.类属性”来调用。不过,一般都是用“类名.类属性”调用。
static变量置于方法区中。
用static声明的方法为静态方法
不需要对象就可以调用(类名.方法名)
在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员。
this
普通方法中,this总是指向调用该方法的对象。
构造方法中,this总是指向正要初始化的对象。
this不能用于static方法。
继承
类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模。
提高代码的复用性。
extends的意思是“扩展”。子类是父类的扩展。
java中只有单继承,没有像c++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。多继承是为了实现代码的复用性,却引入了复杂性,使得系统类之间的关系混乱。
java的多继承,可以通过接口来实现。
如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。
不同的叫法:超类、父类、基类、子类、派生类。
可以将父类作为一个属性,放入子类中(组合)
方法的重写(override)
在子类中可以根据需要对从基类中继承来的方法进行重写。
重写方法必须和被重写方法具有相同方法名称、参数列表和返回值类型。
重写方法不能使用比被重写方法更严的格访问权限。(由于多态)
作业:自己写一个父类(车),再写里两个子类(自行车和小汽车)去继承父类,然后重写父类中的方法(两个以上)。
Object类
Object类是所有java类的基类
如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类
重写toString() 方法
super
super是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性。
普通方法没有顺序限制,可以随便调用。
构造函数,任何类的构造函数中,若是构造函数的第一行代码没有显式的调用super(…);那么java默认都会调用super();作为父类的初始化函数。所以这里的super();加不加都无所谓。
final
修饰变量:常量
修饰方法:该方法不可被子类重写,但可以被重载
修饰类:被final修饰的类不能有子类,不能被继承。比如:Math、String.
封装
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性和可维护性。
程序设计追求“高内聚、低耦合”。
高内聚就是类的内部数据操作细节自己完成,不允许外部干涉。
低耦合就是仅暴露少量的方法给外部使用。
访问控制修饰符
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。
default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
public : 对所有类可见。使用对象:类、接口、变量、方法
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
注意:default和protected的区别在视频一小时15分钟左右
我们可以可以通过以下表来说明访问权限:

封装的要点:
类的属性的处理:
一般使用private(除非本属性确定会让子类继承)
提供相应的get/set方法来访问相关属性,这些方法通常是public,从而提供对属性的读取操作。boolean类型的get方法默认名字是is开头。
一般只用于本类的方法也使用private修饰。希望其他类调用的方法用public修饰。
多态
多态是同一个行为具有多个不同表现形式或形态的能力。
现实中,比如我们按下 F1 键这个动作:
如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
如果当前在 Word 下弹出的就是 Word 帮助;
在 Windows 下弹出的就是 Windows 帮助和支持。
同一个事件发生在不同的对象上会产生不同的结果。
多态的优点:
1. 消除类型之间的耦合关系
2. 可替换性
3. 可扩充性
4. 接口性
5. 灵活性
6. 简化性
多态的三个必要条件
继承
重写
父类应用指向子类对象
多态的实现方式
方式一:重写
这个内容已经在上一章节详细讲过,就不再阐述,详细可访问:Java 重写(Override)与重载(Overload)。
方式二:接口
1. 生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。
2. java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。具体可以看 java接口 这一章节的内容。
方式三:抽象类和抽象方法
instanceof运算符
java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
抽象类
抽象类是一个模板模式。抽象类为所有子类提供了一个通用模板,子类可以在这个模板基础上进行扩展。
通过抽象类,可以避免子类设计的随意性。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。
要点:
有抽象方法的类只能定义为抽象类
抽象类不能实例化,不能用new来实例化抽象类。
抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用。
抽象类只能用来继承。
抽象方法必须被子类实现。
接口
接口(英文:interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过实现接口的方式,从而来实现接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口的特性:
1.接口可以多继承
2.接口的方法声明必须是 public abstract 即便不写默认也是
3.接口里面不能包含方法具体实现(jdk1.8之前)
4.类继承接口必须实现接口里声明的全部方法,除非该类是抽象类
5.接口里面可以声明 public static final 修饰的变量
6.接口不能被实例化,但是可以被实现类创建
内部类
一般情况,我们把类定义成独立的单元。有一些情况下,我们把一个类放在另一个类的内部定义,成为内部类。
内部类的作用:
内部类提供了更好的封装。只能让外部类直接访问,不允许同一个包中的其他类直接访问。
内部类可以直接访问外部类的私有属性,内部类被当成其它外部类的成员。但外部类不能访问内部类的内部属性。
内部类的使用场合:
由于内部类提供了更好的封装特性,并且可以很方便的访问外部类的属性。所以,通常内部类在只为所在外部类提供服务的情况下优先使用。
内部类的分类
静态内部类(内部类中最简单的形式)
1、声明在类体中,方法体外,并且使用static修饰的内部类
2、访问特点可以类比静态变量和静态方法
3、脱离外部类的实例独立创建
在外部类的外部创建内部类的实例
new Outer.Inner();
在外部类的内部创建内部类的实例
new Inner();
4、静态内部类体可以直接访问外部类中所有的静态成员,包括私有
成员内部类(实例内部类)
1、没有使用static修饰的内部类。
2、在成员内部类中不允许出现静态变量和静态方法的声明。
static只能用在静态常量的声明上
3、成员内部类中可以访问外部类中所有的成员(变量、方法),包含私有成员,如果在内部类中定义有和外部类同名的实例变量,访问:
Outer.this.outerMember;
4、构建内部类的实例,要求必须外部类的实例先存在
外部类的外部/外部类的静态方法:new Outer().new Inner();
外部类的实例方法:
new Inner();
this.new Inner();
局部内部类
1、定义在方法体,甚至比方法体更小的代码块中
2、类比局部变量
3、局部内部类是所有内部类中使用最少的一种形式。
4、局部内部类可以访问的外部类的成员根据所在方法体不同。
如果在静态方法中:
可以访问外部类中所有静态成员,包含私有
如果在实例方法中:
可以访问外部类中所有的成员,包含私有
局部内部类可以访问所在方法中定义的局部变量,但是要求局部变量必须使用final修饰。
匿名内部类
1、没有名字的局部内部类。
2、没有class、interface、implements、extends关键字
3、没有构造器
4、一般隐式的继承某一个父类或者实现某一个接口
数组
数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同。
Java 语言中提供的数组是用来存储固定大小的同类型元素。
你可以声明一个数组变量,如 numbers[100] 来代替直接声明 100 个独立变量 number0,number1,…,number99。
数组的声明
dataType[] arrayRefVar; // 首先方法 dataType arrayRefVar[]; // 效果相同,但不是首选方法
实例:
int[] arrayInt; // 首先方法 int arrayInt[]; // 效果相同,但不是首选方法
建议使用 dataType[] arrayRefVar 的声明风格声明数组变量。 dataType arrayRefVar[] 风格是来自 C/C++ 语言 ,在Java中采用是为了让 C/C++ 程序员能够快速理解java语言。
创建数组:
int[] arrayInt = new int[4];
数组元素赋值:
arrayInt[0] = 0;
arrayInt[1] = 1;
arrayInt[2] = 2;
arrayInt[3] = 3;
数组下标从0开始,到数组长度-1为止。
直接赋值的方式:
int[] arrayInt = {0,1,2,3,4,5};
作业:快速排序、冒泡排序|希尔排序、归并排序
int[] arr = {23, 100, 40, 45, 45, 67, 32, 12, 5, 13, 53, 68};
数组的操作
数组的拷贝
System类中包含了一个arraycopy(public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);)方法,该方法可以将src数组里的元素值赋给dest数组的元素,其中srcpos指定从src数组的第几个元素开始赋值,length参数指定将src数组的多少个元素赋值给dest数组的元素。
public class ArrayTest1 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7};
int[] arr1 = {8, 9, 10, 11, 12, 13};

    System.arraycopy(arr, 2, arr1, 2, 3);
    for (int i : arr1) {
        System.out.printf(i + "\t");
    }
}

}
使用Arrays类
打印数组:
public class ArraysTest {
public static void main(String[] args) {
int[] arr = {23, 100, 40, 45, 45, 67, 32, 12, 5, 13, 53, 68};
System.out.println(arr);
System.out.println(Arrays.toString(arr));
}
}
数组的排序
public class ArraysTest {
public static void main(String[] args) {
int[] arr = {23, 100, 40, 45, 45, 67, 32, 12, 5, 13, 53, 68};
System.out.println(arr);
System.out.println(Arrays.toString(arr));

    Arrays.sort(arr);
    System.out.println(Arrays.toString(arr));
}

}
输出结果:
[I@1922e15b
[23, 100, 40, 45, 45, 67, 32, 12, 5, 13, 53, 68]
[5, 12, 13, 23, 32, 40, 45, 45, 53, 67, 68, 100]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值