JavaSE面向对象基础
重点回顾
数组创建
- 动态创建:数据类型[ ] 数组变量名=new 数据类型 [元素个数]
- 静态创建:数据类型[ ] 数组变量名= [元素1,元素2…]
- 动态创建并赋初始值:数据类型[ ] 数组变量名=new 数据类型 [ ] {元素1,元素2…}
数组特点:
- 只能存储相同类型的数据
- 数组中的值可以重复
- 数组的长度是固定的
- 数组是连续的内存空间
系统预定义类型引入
-
基本类型及包装类
-
字符串类型
-
日期类型基础
-
随机数
Math.random()
Random r = new Random()面向对象概论
三大特征:封装、继承、多态
-
封装隐藏了类的内部机制。从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据
(隐藏功能或者信息的细节,使用者只关注功能的使用,而不需要关心实现细节) -
继承是为了重用父类代码,同时为实现多态性做准备
- 关键字extends,子类可以继承父类的成员变量和成员方法 - Java采用的是单根继承体系
-
多态是发送消息给某个对象,让该对象自行决定响应何种行为,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用
- 一个事物可以有多种表现形式 - 体现形式常见的有3种 (父类型引用子类对象、方法重写、方法重载)
面向对象三大特征的优缺点:
- 设计目标:高内聚低耦合
- 可维护性高
- 重用性提高
- 扩展性增强
- 执行效率
概述
面向过程是一种自上而下的程序设计方法,主要思路专注于算法的实现
自上而下的设计方法,设计者用一个main函数概括出整个应用需要做的事情,然后把main方法拆解成不同的步骤,对应不同的函数
过程式的特征是以函数为中心,用函数作为划分程序的基本单位;数据在过程式设计中处于从属的位置
过程式设计的优点是易于理解和掌握,这种逐步细化问题的设计方法与大多数人的思维方式比较接近
过程式设计是自上而下,这就要求设计者在开始时要对需要解决的问题有一定的理解,然而在问题比较复杂时,要做到这一点比较困难;当开发需求变化时,以前对问题的理解会变得不再适用
软件代码的重用性很差,即使重用,也是简单的复制和拷贝,代码数量急剧增加。而不能直接继承和应用
面向过程的方法将数据和过程分离,使得数据的改变很可能带来代码的变化
面向对象是一种自下而上的程序设计方法,以数据为中心,类是表现数据的单位,是划分程序的基本单位
面向对象设计是自下而上的特性,允许开发者从问题的局部开始,在开发过程中逐步加深对系统的理解。需求变化会作用到系统开发本身,形成一种螺旋式的开发方式
面向对象设计中,类封装了数据,而类的成员函数作为其对外的接口,抽象地描述类,用类将数据和操作这些数据的函数放在一起,这就是面向对象设计方法的本质
面向对象的概念
面向对象Object Oriented是软件开发方法
-
面向对象是一种新兴的程序设计方法,或者是一种新的程序设计规范paradigm,其基本思想是使用对象、类、继承、封装、消息等基本概念来进行程序设计
-
从现实世界中客观存在的事物(即对象)出发来构造软件系统,并且在系统构造中尽可能运用人类的自然思维方式
-
开发一个软件是为了解决某些问题,这些问题所涉及的业务范围称作该软件的问题域。其应用领域不仅仅是软件,还有计算机体系结构和人工智能等
-
面向对象的思想已经涉及到软件开发的各个方面。如面向对象的分析(OOA,Object OrientedAnalysis),面向对象的设计(OOD,Object Oriented Design)、以及我们经常说的面向对象的编程实现(OOP,Object Oriented Programming)
-
OOP使得现实世界中的概念在计算机程序中编程模块,它包括构造程序的特征以及组织数据和算法的机制
面向对象是一种对现实世界理解和抽象的方法 -
传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象
-
OOP语言有3大特征:封装、继承及多态,所有这些特征与类的概念是息息相关的
-
面向对象是指一种程序设计范型,同时也是一种程序开发的方法。对象指的是类的集合。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。
对象、类、实体之间的关系和面向对象的问题求解思维方式
对象
对象是要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。对象是一个客观存在的、唯一的实体,是一个类的动态实例,拥有自己的标识、数据与行为
- 在现实世界中:是客观世界中的一个实体
- 在计算机世界中:是一个可标识的存储区域
- 现实世界中所有的事物都是对象
- 对象都具有某些特征,并展现某些行为
对象的状态和行为
- 对象具有状态,一个对象用数据值来描述它的状态
- 对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为
- 对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中
对象的两个要素
- 属性:用于描述对象静态特性(结构特性)的一个数据项,描述一个人可用姓名、性别、身份证号等属性
- 方法(也称服务):用于描述对象动态特性(行为特性)的一个操作系列 。 每个人都具有工作、学习等行为特性
- 对象将数据和施加于数据上的操作打包成一个不可分割的最基本的模块,使得仅有该类的有限个方法才可以操纵、改变这些数据
类
用java语言对现实生活中的事物进行描述,通过类的形式来体现
- 类是具有共同属性和行为的对象的抽象,具有相同特性(数据元素)和行为(功能)的对象的抽象就是类
- 对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象
- 类实际上就是一种数据类型
- 类是用于组合各个对象所共有操作和属性的一种机制
- 类是具有相同属性和行为的一组对象的集合
(- 类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性
- 类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述)
- - 类可以定义为数据和方法的集合,类也称为模板,因为它们提供了对象的基本框架
一旦定义类后,就可以用这种新类来创建该类型的对象
( 类就是对象的模板(template)
而对象就是类的一个实例(instance)
)
消息和方法
- 对象之间进行通信的结构叫做消息。发送一条消息至少要包括说明接受消息的对象名、发送给该对 象的消息名(即对象名、方法名)
- 类中操作的实现过程叫做方法,一个方法有方法名、返回值、参数、方法体
类和对象之间的关系
类是事物的描述
- 类是Java程序的核心,它定义了对象的形状和本质,可以用类来创建对象。当使用一个类创建了一 个对象时,通常说给出了这个类的一个实例
- 类由类声明和类体构成,一般命名方法为:首字母大写,大写字母分词,例如XueSheng
class className{
类体;
}
- 类包含数据成员(数据、属性)和成员方法(函数)。一般建议数据成员应该是通过函数(方法)访问的
- 对象是类的实例,就是应用中定义的某个类的变量,例如Person p=new Person();p就是对象
- 类是和问题域相关的具有相同属性和行为的对象的抽象;对象是该类事物的实例,在Java中通过new来创建的
封装
在面向对象程式设计方法中,封装Encapsulation是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
-
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问
反射机制 -
要访问该类的代码和数据,必须通过严格的接口控制
-
封装最主要的功能在于能修改自己的实现代码,而不用修改那些调用代码的程序片段
-
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
//第一步是确定研究的目标对象--可以区分的独立个体
//需要方法和属性
class Student{
//成员属性---静态特征的描述
private boolean sex;//一般私有属性,共有的get/set方法
//成员方法---提供的功能描述
public boolean getSex(){
return this.sex;
}
//不允许修改sex,所以不提供set方法
protected void setSex(Boolean sex){
//如果在特殊情况下允许修改,可以使用范围限定词进行表示
this.sex=sex;
}
}
//构建对象
Student s1 = new Student();
s1.setSex(true);
s1.sexSex(false);
封装有三大好处
- 良好的封装能够减少耦合
- 类内部的结构可以自由修改
- 可以对成员进行更精确的控制
- 隐藏信息,实现细节
4个关键字
用于进行访问控制
//一个文件种可以定义无数个类,但是只能有一个public class公共类
public class Student{
//成员属性,类型包含哪些静态特征取决于问题本身
private Long id;//private 只能在当前类中直接访问
protected String name;//protected可以在同包或者子类中直接访问
int age;//没有范围限定词,默认或者package限定词,只能在同包中直接访问
public double salary;//public到处可见
//一般规则是私有属性,共有的get/set方法
}
记性方法
类定义规则:要求类内高内聚、类间弱耦合
封装确实可以使容易地修改类的内部实现,而无需修改使用了该类的客户代码
继承
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。
继承是is-a的相互关系
继承的优点
-
将所有子类的共同属性放入父类,实现代码共享,避免重复,提高开发效率
-
可以使得修改扩展继承而来的实现比较简单
继承的缺陷 -
父类变,子类就必须变
-
继承破坏了封装,对于父类而言,它的实现细节对与子类来说都是透明的
-
继承是一种强耦合关系
特殊关键字
包package
包是类或接口的容器,是一个用于避免命名冲突的名空间,是一个逻辑命名的概念,与具体的物理位置无关
在具体的实现中,包名称经常和目录名称对应
什么是包
- 包是类的组织方式,提供名空间和访问控制
- 类似于文件系统的组织
声明包中的类package
语法:package 包名称;
- 声明包要求是源代码文件的第一个语句。包定义之前可以添加注释信息
- 程序中最多只能有一条package语句,没有包定义的源代码文件成为默认包中的一部分
//默认包中的类可以访问其他命名包或者只能同包访问,其他包不能访问默认包中的类
public class A1{
public void cc(){
System.out.println("小胖子醒醒!");
}
}
- 程序中如果有package语句,该语句必须是第一条语句(前面只能有注释或空行)
- 包的命名规则:
。全小写
。使用域名反转的方式定义,例如延安餐饮集团yanan.com的项目,定义包名称为com.yanan
如果细分还可以引入功能定义部分,例如数据库访问com.yanan.dao
包的作用
- 包能将相关的源代码文件组织在一起
- 包减少了名称冲突带来的问题
- 可以使用package指明源文件中的类属于哪个具体的包
包的使用
- 如果其他人想使用包中类,则需要使用全名
import java.util.Date;
public class A{
public static void main(Strinrg[] args){ Date now = new Date();//使用类的简称Date。而不是全名称java.util.Date
}
}
//用法2:全称
java.util.Date now = new java.util.Date();//不需要import
- 为了简化书写,Java提供了import语句:import package_name.*;
import java.util.*;
//使用java.util包中的所有类都不需要再使用import java.util.类名
- 引入包中的某一个类:import java.util.ArrayList;
引入包import
Java缺省引入的包为java.lang
System.out.println(“显示输出:”);//不需要import java.lang.System
//同包中的其他类不需要导入
package com.yan;
public class A{}
package com.yan;
public class B{
public void pp(){
A a=new A1();//不需要import com.yan.A
}
}
- 引入包中的类:import 包名称.类名称;例如import java.util.Date;
- 引入整个包:import 报名称.* 例如 import java.util.*;
- 不引入包而是用类,则需要用类的全名:包名.类名,例如:java.util.Date dd=new java.util.Date();
范围限定词和包
package lainxi11;
//定义不包含再其他类中的外部类时,class前的范围限定词可以使用public或者默认
//public到处可见 没有限定词只能同包访问
public class A{
public static void main(String[] args) {
B b =new B();//语法正确
}
}
class B{}
public class C{
public static void main(String[] args) {
B b =new B1();//语法错误,因为B类时默认class
}
}
//成员属性和成员方法;定义在class内部,除了构造器(匿名内部代码块)和析构器之外的其他内容
public class A{
public A(){}//方法名称和类名称一致,包括大小写,而且没有返回类型声明---构造器
//构造器方法不能直接调用,只能通过new运算符进行间接调用new A()系统自动执行A()方法
public int A(){}//语法正确,但不是构造器,可以直接调用,newA().A()
//成员方法
public 范围限定词 返回数据类型 方法名称(参数类型1 形参名称1,.....){
return xxx;返回值必须和返回类型声明一致,如果返回类型为void 则return后面不能带任何数据
}//成员方法调用为 对象名.方法名称(实际参数列表)
}
包的文件组织和类路径CLASSPATH
在类看路径中定义包的位置
- .代表当前目录,为默认值
- 类文件存放的位置:类路径中的目录\包名称对应的路径
- 缺省包default package
- 源代码文件中没有package语句声明,且类文件位于CLASSPATH所定义的目录中
- 满足以上条件的所有类被认为处在同一个包中,这个包被称为缺省包
classpath描述了Java虚拟机在运行一个class时在那些路径中加载要运行的类要用到的
当一个程序找不到所需的其他类文件时,系统会自动到CLASSPATH环境变量所指明的路径中去查找第三方提供的类和用户定义的类
Java中常用的包
- java.applet用于提供Applet开发的支持,目前已经被flash所替代,很少使用,只有在某些地图系统中还有使用
- java.awt和javax.swing用于单机软件或者c/s应用中的界面开发
- java.io用于输入、输出操作
- java.lang语言包,默认自动加载的包
- java.net用于网络编程
- java.util工具包,是Java提供的一些工具类
基础练习
面向对象的程序是由对象组成的,每个对象包含对用户公开的特定功能部分和隐藏的实现部分。在面向对象程序设计中,不必关心对象的具体实现。在传统的结构化程序设计中,算法是第一位的,数据结构是第二位的,即首先确定如何操作数,再考虑如何组织数据,以方便操作。而OOP则颠倒了这种次序,将数据放在第一位,然后再考虑操作数据的算法。
抽象
忽略掉一个对象或实体的细节而只关注其本质特征的过程,可以简化功能与格式,帮助用户与对象交互是人类解决问题的基本法宝。良好的抽象策略可以控制问题的复杂程度,增强系统的通用性和可扩展性抽象主要包括过程抽象和数据抽象
- 过程抽象是将问题域中具有明确功能定义的操作抽取出来,并将其作为一个实体看待
- 数据抽象是较过程抽象更高级别的抽象方式,将描述客体的属性和行为绑定在一起,实现统一的抽象,从而达到对现实世界客体的真正模拟
类
类是构造对象的模板和蓝图。通俗地说,类相当于建筑的图纸,而对象相当于建筑物。由类构造对象的过程称为创建对象的实例。Java中通过关键字class定义“类”,后跟类名
设计与编写类的过程实际上是一个对实体共有属性和行为的一个抽象的过程
例如面对的是一个具体个体:赵小胖,为了将研究对象存储在计算机中,所以定义了一个新数据类型Student
class Student{}
分析问题域相关的属性:
class Student{
private Long id;//如果使用包装类,则默认值为null
private String usename="zhouyan";
private int age;//如果使用简单类型,则数值默认为0,布尔类型为false
}
分析问题域相关的行为–方法
class Student{
public void study(){}
public void sleep(){}
private Long id;//如果使用包装类,则默认值为null
private String username="周妍";
private int age;
}
定义类的目的就是为了在计算机中存储特定的对象,所以需要创建对应的对象,创建方法和简单类型中定义变量的含义一致`
Student s1=new Student();
s1.方法名();调用成员方法;
new student().sleep;
面向对象的编程可以认为是面向类的编程。编写类的过程,相当于我们定义了一种新的数据类型。
对象对象编程的核心是面向抽象编程,面向抽象编程的核心是面向接口编程
字段和方法
定义一个类时,可以在类里设置两种类型的元素:数据成员和成员函数。其中数据成员是一种对象,可以是任何类型。如果是指向对象的句柄,则必须初始化这个句柄,通过构造器与一个实际对象连接起来。如果是基本数据类型,则可以在类定义的位置直接初始化。
public class Student{
private int age;
private String username;
private Course[] Courses;
}
public class Course{
}
引用和指针的区别:
引用也叫句柄,类似于指针,但是和指针是不同的。指针是一个存放地址的变量,使程序员可以灵
活的访问内存,由于可以对指针进行任意的运算操作,所以给程序带来了安全隐患和意想不到的结
果。引用继承了指针节省内存的优点,但是限制了对地址的操作,它是安全的。Java中所有的变量
都是一个引用,java中没有指针的概念。
每个对象都为自己的数据成员保有存储空间;数据成员不会在对象之间共享。
Student s1 = new Student();
Student s2 = new Student();
s1.setName("...");
System.out.println(s2.getName);
通过一个new关键字创建一个对象
成员变量和局部变量的区别
成员变量定义在类中,整个类中都能访问
class Student{
private String username;//成员变量-属性--字段()定义在类中所有方法之外,在整个类体的范围内有效,和具体的定义位置无关
}
局部变量定义在方法、语句、局部代码中,只在所属的区域中有效,而且必须是先定义后使用,必须是先赋初值后使用
public static void pp(){
int kk = 100;//局部变量
for(int kk =0;;){}//局部变量
}
成员变量存在于堆内存的对象中,堆内存中的对象大小可以任意,并允许在运行时进行调整。所以访问查找的效率比较低。
局部变量存在与栈内存的方法中,可以快速定位,但是大小是限定的
成员变量随着对象的创建而存在,随着对象的表示而消失。局部变量随着所属区域的执行而存在,随着所属区域的结束而释放
成员变量都有默认初始化值;局部变量没有默认初始化值
用句柄操作对象
尽管Java是完全面向对象的。但是,操作的标识符实际指向一个对象的句柄,又称引用。句柄是可以独立存在的,并不是说,拥有一个句柄就必须有一个对象与之对应。比如,inti定义了一个整型变量i,并不表示它一定有值
在Java中方法的调用形式为 对象名.方法名
方法
方法可以理解为一个命名的代码块,通过名称就可以重复使用这段代码,而不需要反复书写,可以达到代码重用的目的
- 参数:是指进入方法中的数据,有了这些数据,方法才能执行逻辑
- 返回值:是指从方法中出来的数据,也就是方法执行之后的最终结果数据。
方法可以有参数,也可以没有参数;方法可以有返回值,也可以没有返回值
目前定义方法的基本格式:
修饰符 返回值类型 方法名称(参数类型 参数名称){
方法体
return 返回值;
}
- 修饰符
- 返回值类型:方法最终产生的结果数据是什么类型
- 方法名称:自定义的名称,命名规则和变量一样
- 参数类型:进入方法的数据是什么类型
- 参数名称:进入方法的数据对应的变量名称
- 方法体:方法内部执行的若干行代码
- return:结束方法的执行,并且将返回值返还给调用处
- 返回值:方法最终产生的结果数据。
注意:
- 返回值必须和返回值类型对应
- 参数如果有多个,需要使用逗号分隔
- 参数如果没有,小括号则可以留空
- 多个方法的定义先后顺序无所谓
- 不能在一个方法内部定义方法
- 方法定义之后,没有调用就不会执行;要想执行,一定要调用它。
参数传递
- 形式参数:在定义方法的时候,写在小括号之内的变量,就叫形式参数。实际上在方法定义中起到占位符的作用,会在方法调用时被传递过来的实际值所替代
- 实际参数:在调用方法的时候,真正传入方法里的数据,叫做实际参数。
圆括号中的实参列表为调用方法时实际传入的实际参数,称为实参列表。声明方法时圆括号中的参数称为形式参数,形式参数和实际参数在数据类型和个数上一定要匹配
注意:调用方法时形式参数和实际参数的个数和顺序必须一致,数据类型也必须相同。
- return 123;表示返回结果123,这个值将返回调用处。当然要求返回值的类型和声明的返回值类型一致
public void pp(){
return null;//语法错误,返回值类型为void的方法体中,只能使用return;
}
- return 123;表示返回结果为123,这个值将返回到调用处。当然要求返回值的类型和声明的返回值类型一致
public void pp(){
return null;//语法错误,返回值类型为void的方法体中,只能使用return;
}
- return;表示从这里结束方法的执行,并返回调用处,但是没有具体的返回值。这里要去声明时的返回值类型为void
重名问题 - 变量的名称是否可以与方法名称重名?可以
- 两个不同的方法中,能否各自有一个重名的变量?可以
基础练习:
判断一个字符串是否是回文数
String ss = "123321";
String s2 = new StringBuilder(ss).reverse().toString();
System.out.println(s2);
System.out.println(ss.equals(s2));
面向对象和面向过程的区别
面向过程
优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
缺点:没有面向对象易维护、易复用、易扩展
面向对象:
优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
缺点:性能比面向过程低