面向过程是一种自上而下的程序设计方法,主要思路专注于算法的实现
自上而下的设计方法,设计者用一个main函数概括出整个应用需要做的事情,然后把main方法拆解成不同的步骤,对应不同的函数
过程式的特征是以函数为中心,用函数作为划分程序的基本单位;数据在过程式设计中处于从属的位置
过程式设计的优点是易于理解和掌握,这种逐步细化问题的设计方法与大多数人的思维方式比较接近
过程式设计是自上而下,这就要求设计者在开始时要对需要解决的问题有一定的理解,然而在问题比较复杂时,要做到这一点比较困难;当开发需求变化时,以前对问题的理解会变得不再适用
软件代码的重用性很差,即使重用,也是简单的复制和拷贝,代码数量急剧增加。而不能直接继承和应用
面向过程的方法将数据和过程分离,使得数据的改变很可能带来代码的变化
面向对象是一种自下而上的程序设计方法,以数据为中心,类是表现数据的单位,是划分程序的基本单位
面向对象设计是自下而上的特性,允许开发者从问题的局部开始,在开发过程中逐步加深对系统的理解。需求变化会作用到系统开发本身,形成一种螺旋式的开发方式
面向对象设计中,类封装了数据,而类的成员函数作为其对外的接口,抽象地描述类,用类将数据和操作这些数据的函数放在一起,这就是面向对象设计方法的本质
面向对象Object Oriented是软件开发方法
面向对象是一种新兴的程序设计方法,或者是一种新的程序设计规范paradigm,其基本思想是使用对象、类、继承、封装、消息等基本概念来进行程序设计
从现实世界中客观存在的事物(即对象)出发来构造软件系统,并且在系统构造中尽可能运用人类的自然思维方式
开发一个软件是为了解决某些问题,这些问题所涉及的业务范围称作该软件的问题域。其应用领域不仅仅是软件,还有计算机体系结构和人工智能等
面向对象的思想已经涉及到软件开发的各个方面。如面向对象的分析(OOA,Object OrientedAnalysis),面向对象的设计(oOD,Object Oriented Design)、以及我们经常说的面向对象的编程实现(OOP,Object Oriented Programming)
OOP使得现实世界中的概念在计算机程序中编程模块,它包括构造程序的特征以及组织数据和算法的机制
面向对象是一种对现实世界理解和抽象的方法
传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器",即对象
OOP语言有3大特征:封装、继承及多态,所有这些特征与类的概念是息息相关的
面向对象是指一种程序设计范型,同时也是一种程序开发的方法。对象指的是类的集合。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性
对象、类、实体之间的关系和面向对象的问题求解思维方式
对象是要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。对象是一个客观存在的、唯一的实体,是一个类的动态实例,拥有自己的标识、数据与行为
在现实世界中:是客观世界中的一个实体
在计算机世界中:是一个可标识的存储区域
现实世界中所有的事物都是对象
对象都具有某些特征,并展现某些行为
对象的状态和行为
对象具有状态,一个对象用数据值来描述它的状态
对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为
对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中
对象的两个要素
用Java语言对现实生活中的事物进行描述,通过类的形式来体现
类是具有共同属性和行为的对象的抽象,具有相同特性(数据元素)和行为(功能)的对象的抽象就是类
对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象
类实际上就是一种数据类型
类是用于组合各个对象所共有操作和属性的一种机制
类是具有相同属性和行为的一组对象的集合
类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性
类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述
一旦定义类后,就可以用这种新类来创建该类型的对象
类就是对象的模板(template )
而对象就是类的一个实例( instance)
类是事物的描述
class className{
类体
}
类包含数据成员(数据、属性)和成员方法(函数)。一般建议数据成员应该是通过函数(方法)访问的
对象是类的实例,就是应用中定义的某个类的变量,例如Person p=new Person(); p就是对象
类是和问题域相关的具有相同属性和行为的对象的抽象;对象是该类事物的实例,在Java中通过new来创建的
在面向对象程式设计方法中,封装Encapsulation是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问
反射机制
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于能修改自己的实现代码,而不用修改那些调用代码的程序片段
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
//第一步是确定研究的目标对象---可以区分的独立个体l雷要方法和属性
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 (false);//是否允许取绝于限制
}
良好的封装能够减少耦合
类内部的结构可以自由修改
可以对成员进行更精确的控制
隐藏信息,实现细节
用于进行访问控制
//一个文件种可以定义无数个类,但是只能有一个public class公共类
public class Student {
//成员属性,类种包含哪些静态特征取决于问题本身
private Long id; // private只能在当前类中直接访问
protected String name; //protected可以在同包或者子类中直接访问
int age; //没有范围限定词,默认或者package限定词,只能在同包中直接访问public double salary ; / /public到处可见
//一般规则是私有属性,共有的get/set方法
}
记忆的方法
当前类内 | 同包 | 子类 | 到处 | |
---|---|---|---|---|
private | T | |||
无范围限定词 | T | T | ||
protected | T | T | T | |
public | T | T | T | T |
类定义规则:要求类内高内聚,类间弱耦合
例子:计算装修费用
查找名词:房间(多个墙)墙(长.高)窗户(长、宽)…
继承就是子类继承父类的特征和行为,使得子类对象〈实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。
继承是is-a的相互关系
将所有子类的共同属性放入父类,实现代码共享,避免重复,提高开发效率
可以使得修改扩展继承而来的实现比较简单
父类变,子类就必须变
继承破坏了封装,对于父类而言,它的实现细节对与子类来说都是透明的·继承是一种强耦合关系
包是类的组织方式。提供名空间和访问控制
类似于文件系统的组织
语法:package 包名称;
声明包要求是源代码文件的第一个语句。包定义之前可以添加注释信息
程序中最多只能有一条package语句,没有包定义的源代码文件成为默认包中的一部分
/ /默认包中的类可以访问其它命名包或者只能同包访问,其它包不能访问默认包中的类
public class A1 {
public void cco {
System.out.println("我就不");
}
}
程序中如果有package语句,该语句必须是第一条语句(前面只能有注释或空行)
包的命名规则:
全小写
使用域名反转的方式定义,例如延安餐饮集团yanan.com的项目,定义包名称为com.yanan
如果细分还可以引入功能定义部分,例如数据库访问com.yanan.dao
包能将相关的源代码文件组织在一起
包减少了名称冲突带来的问题
可以使用package指明源文件中的类属于哪个具体的包
import java.uti1.Date;
public class A{
public static void main(string[] args){
Date now=new Date();//使用类的简称Date,而不是全名称java.util.Date
}
}
//用法2:全称
java.uti7.Date now=new java.uti1.Date();//不需要import
import java.uti1.*;
//使用java.uti1包中的所有类都不需要再使用import java.uti7.类名
System.out.println("显示输出");//不需要import java.lang.system
//同包中的其它类不需要导入
package com.zhao;public class A{}
package com.zhao;
public class B{
public void pp(){
A a=new Al();//不雷要import com.zhao.A
}
}
引入包中的类: import包名称.类名称;例如import java.util.Date;
引入整个包;import包名称.;例如import java.uti7. ;
不引入包而是用类,则需要是用类的全名:包名.类名,例如java.util.Date dd=new java.util.Date();
//定义不包含再其它类中的外部类时,class前的范围限定词可以使用public或者默认/ / public到处可见没有限定词只能同包访问
package com.zhao;
public class A{
public static void main(string args){
B b=new B();//语法正确
}
}
class B{}
package com.zhao1;
public class c{
public static void main(String[] args){
B b=new B1();//语法错误,因为B类是默认c1ass
//成员属性和成员方法:定义在class内部,除了构造器(匿名内部代码块)和析构器之外的其它内容
public class A{
public A(){}//方法名称和类名称一致,包括大小写,而且没有返回类型声明---构造器//构造器方法不能直接调用,只能通过new运算符进行间接调用new A()系统自动执行A()方法
public int A(){} //语法正确,但是不是构造器。可以直接调用, new A().A()
//成员方法public范围限定词返回数据类型方法名称(参数类型1形参名称1,...){/ /如果没有返回值则类型为void
//return xxX;返回值必须和返回类型声明一致;如果返回类型为void则return后面不能带任何数据
}//成员方法的调用为对象名.方法名称(实际参数列表)
}
在类路径中定义包的位置
代表当前目录,为默认值
类文件存放的位置:类路径中的目录\包名称对应的路径
缺省包default package
源代码文件中没有package语句声明,且类文件位于CLASSPATH所定义的目录中
满足以上条件的所有类被认为处在同一个包中,这个包被称为缺省包
Classpath描述了Java虚拟机在运行一个Class时在哪些路径中加载要运行的类以及运行的类要用到的类当一个程序找不到他所需的其他类文件时,系统会自动到CLASSPATH环境变量所指明的路径中去查找第三方提供的类和用户定义的类
java.applet用于提供Applet开发的支持,目前已经被lash所替代,很少使用,只有在某些地图系统中还有使用
java.awt和javax.swing用于单机软件或者c/s应用中的界面开发
java.io用于输入、输出操作
java.lang语言包,默认自动加载的包java.net用于网络编程
java.util工具包,是Java提供的一些工具类
忽略掉一个对象或实体的细节而只关注其本质特征的过程,可以简化功能与格式,帮助用户与对象交互是人类解决问题的基本法宝。良好的抽象策略可以控制问题的复杂程度,增强系统的通用性和可扩展性抽象
主要包括过程抽象和数据抽象
过程抽象是将问题域中具有明确功能定义的操作抽取出来,并将其作为一个实体看待
数据抽象是较过程抽象更高级别的抽象方式,将描述客体的属性和行为绑定在一起,实现统一的抽象,从而达到对现实世界客体的真正模拟
类是构造对象的模板和蓝图。通俗地说,类相当于建筑的图纸,而对象相当于建筑物。由类构造对象的过程称为创建对象的实例。Java中通过关键字class定义“类”,后跟类名
设计与编写类的过程实际上是一个对实体共有属性和行为的一个抽象的过程
例如面对的是一个具体个体:东方,为了将研究对象存储在计算机中,所以定义了一个新数据类型student
class Student
分析问题域相关的属性:
class Student {
private Long id;//如果使用包装类,则默认值为null
3
private String username="xiaopang" ;
private int age;//如果使用简单类型,则数值型默认为0,布尔型为false
}
分析问题域相关的行为一方法
class Student{
public void studyO{]}
public void sleepo{}
private Long id;//如果使用包装类,则默认值为null
private String username="xiaopang" ;
private int age;
}
定义类的目的就是为了在计算机中存储特定的对象,所以需要创建对应的对象,创建方法和简单类型中定义变量的含义一致
面向对象的编程可以认为是面向类的编程。编写类的过程,相当于我们定义了一种新的数据类型。
定义一个类时,可以在类里设置两种类型的元素:数据成员和成员函数。其中数据成员是一种对象,可以是任何类型。如果是指向对象的句柄,则必须初始化这个句柄,通过构造器与一个实际对象连接起来。如果是基本数据类型,则可以在类定义的位置直接初始化。
public class Student{
private int age;//属性在不赋值时会有默认值
private String username ;
private Course[] courses ;
}
public class course{
}
引用和指针的区别:
引用也叫句柄,类似于指针,但是和指针是不同的。指针是一个存放地址的变量,使程序员可以灵活的访问内存,由于可以对指针进行任意的运算操作,所以给程序带来了安全隐患和意想不到的结果。引用继承了指针节省内存的优点,但是限制了对地址的操作,它是安全的。Java中所有的变量都是一个引用, java中没有指针的概念。
l
Student s1=new student(;
Student s2=new Student(;
s1.setName("盘子");
System.out.println(s2.getName() ;
通过new关键字创建一个对象
成员变量定义在类中,整个类中都能访问
class Student{
private String username;//成员变量-属性---字段(?)定义在类中所有方法之外,在整个类体的范围内有效,和具体的定义位置无关
}
局部变量定义在方法、语句、局部代码块中,只在所属的区域中有效,而且必须是先定义后使用,必须是先赋初值后使用
public static void ppo{
int kk=100;//局部变量
for(int k=0 ;;){}//局部变量
}
成员变量存在于堆内存的对象中,堆内存中的对象大小可以任意,并允许在运行时进行调整。所以访问查找的效率比较低。
局部变量存在与栈内存的方法中,可以快速定位,但是大小是限定的
成员变量随着对象的创建而存在,随着对象的表示而消失。局部变量随着所属区域的执行而存在,随着所属区域的结束而释放
成员变量都有默认初始化值;局部变量没有默认初始化值
尽管Java是完全面向对象的。但是,操作的标识符实际指向一个对象的句柄,又称引用。句柄是可以独立存在的,并不是说,拥有一个句柄就必须有一个对象与之对应。比如,int i定义了一个整型变量i,并不表示它一定有值
在Java中方法的调用形式为对象名.方法名
方法可以理解为一个命名的代码块,通过名称就可以重复使用这段代码,而不需要反复书写,可以达到代码重用的目的
参数:是指进入方法中的数据,有了这些数据,方法才能执行逻辑
返回值:是指从方法中出来的数据,也就是方法执行之后的最终结果数据。
方法可以有参数,也可以没有参数;方法可以有返回值,也可以没有返回值
目前定义方法的基本格式:
修饰符返回值类型方法名称(参数类型参数名称){
方法体
return返回值:
}
修饰符
返回值类型:方法最终产生的结果数据是什么类型·方法名称:自
定义的名称,命名规则和变量一样
参数类型:进入方法的数据是什么类型
参数名称:进入方法的数据对应的变量名称
方法体:方法内部执行的若干行代码
return:结束方法的执行,并且将返回值返还给调用处·返回值:方法最终产生的结果数据。
注意:
返回值必须和返回值类型对应
参数如果有多个,需要使用逗号分隔
参数如果没有,小括号则可以留空
多个方法的定义先后顺序无所谓
不能在一个方法内部定义方法
方法定义之后,没有调用就不会执行;要想执行,一定要调用它。参数传递
形式参数:在定义方法的时候,写在小括号之内的变量,就叫形式参数。实际上在方法定义中起到占位符的作用,会在方法调用时被传递过来的实际值所替代
实际参数:在调用方法的时候,真正传入方法里的数据,叫做实际参数。
圆括号中的实参列表为调用方法时实际传入的实际参数,称为实参列表。声明方法时圆括号中的参数称为形式参数,形式参数和实际参数在数据类型和个数上一定要匹配
注意:调用方法时形式参数和实际参数的个数和顺序必须一致,数据类型也必须相同。
变量的名称是否可以与方法名称重名?可以。
两个不同的方法中,能否各自有一个重名的变量?可以。基础练习;
1、判断一个字符串是否是回文数思路:反转字符串和原始字符串一致
String ss = "123219";
String s2 = new StringBuilder(ss).reverse().tostring();
System.out.println(s2);
System.out.println(ss.equa1s(s2));
面向过程:
优点: 性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、 Linux/Unix等━般采用面向过程开发,性能是最重要的因素。
缺点: 没有面向对象易维护、易复用、易扩展
面向对象:
优点: 易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
缺点: 性能比面向过程低
public static void main(String[] args){}
理解main()方法语法及命令行参数: main方法入口是一个数组类型的参数,也可以给main方法传递参数,通过命令行在运行时传入参数即可。main方法的参数是String数组,命令行运行Java程序时,可以传入多个参数,args[0]访问第一个参数,args[1]访问第二个参数,args[3]访问第三个参数,该程序运行时,需要在命令行传入三个参数。
构造函数是一种特殊的方法,不算是成员方法。主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
public class A{
public A(){//不能有返回值类型的声明,甚至void都不允许出现
}
public A(int k)
public A(String name){}
public A(int k ,String name){}
一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们,即构造函数的重载。
new A();//对应的构造器为A({}
new A(100);//对应的构造器为A(int k){
new A(true);//因为没有A(Boolean kk)这样的构造器,所以语法报错
函数名与类名相同,包括大小写
不用定义返回值类型,不用写void。不能return具体指,可以使用return没有返回值
没有具体的返回值
一个类可以有多个不同的构造器,但是参数一定不能相同
Java中并不识别参数名称
在构造函数前面加上返回值就只是一般函数了
构造器用于给对象进行初始化,可创建对象new构造函数();
public class student{
private String name;
private int age ;
//出现了2个同名的name变量,一个成员变量,一个局部变量。可以使用this进行区分,this.name标识成员变量,直接使用name表示局部变量。
public student(String name ,int age){
this.name=name ;
this.age=age;
}
System.out.println(name);//按照就近原则,这个name用于指代局部变量
}
当使用new运算符时自动进行调用,但是构造方法不能直接调用
关键字new通常称为创建运算符,用于分配对象内存,并将该内存初始化为缺省值
一旦new完成分配和初始化内存,它就将调用构造函数来执行对象初始化
当定义Java类时没有定义构造器,则ava自动为类自动提供无参构造器,将成员变量的值初始化为缺省值
简单类型属性:数值型为0,boolean为false,char为lu000o
复杂类型属性: null
一旦创建了自己的构造函数,缺省的构造函数将不复存在
public class student{
private String national="汉族";
public student(){
this.national="民族";
}
}
每个类至少有一个构造方法。
一个类中如果没有定义过构造函数,那么该类中会有一个默认的空参数构造函数
如果在类中定义了指定的构造函数,那么类中的默认构造函数就没有了
尽量不在类的构造器中创建、初始化大量的对象或执行某种复杂、耗时的运算逻辑
构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化new A()
一般函数:对象创建后,需要函数功能时才调用
构造函数:对象创建时,会调用并且只调用一次
一般函数:对象创建后,可以被调用多次
析构方法–析构器—在垃圾回收之前运行的方法—资源回收
@override
protected void finalize() throws Throwable {
//ToDO Auto-generated method stub
super.finalize();
}
由于垃圾回收的执行时机不确定,而且不能保证一定会执行析构器,所以一般不能使用析构方法执行资源回收
finalize()方法无法保证一定会执行,jdk10+已弃用此方法
继承就是在已经存在的类的基础上进行扩展,从而产生新的类,支持了层次结构分类的概念。已经存在的类称为父类、超类或基类,而新产生的类称为子类或派生类。多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。多个类可以称为子类,单独这个类称为父类或者超类。
通过extends 关键字让类与类之间产生继承关系
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。
继承是is-a的相互关系
在Java中父类所拥有的一切,子类都可以继承
私有属性是否可被继承–两种答案
子类除了拥有父类的属性和方法(拥有父类的所有成员,但是注意构造器和析构器不是成员),也可以创建自己的特性
public class Anima1{
private Long id;
private String type;
public void pp(){}
public class Person extends Anima1{
private String username ;
//这里就包含了方法pp
}
可以减少代码,而且易于维护
建议的使用场景︰把通用操作和方法放在父类中,将特殊的方法定义在子类中。好处在于:1、避免代码重复。2、避免了人为因素导致的不一致性
1、Java中不支持多重继承。Java中要求任何的子类只能有一个直系的双亲类
public class A extends B,C{}//语法错误,因为A只能继承一个类或者不写继承
原因:因为多继承容易出现问题。两个父类中有相同的方法,子类到底要执行哪一个是不确定的
如果定义类但是没有extends,则意味着默认父类为java.Jlang.Object。这也就是说Java中的任意类都是Object的子类
2、如果定义类但是没有extends,则意味着默认父类为java.lang.0bject。这也就是说Java中的任意类都是Object的子类
3、可以在子类中进行覆盖定义父类中的成员方法和成员属性
public class A{
protected long id;
public class B extends A{
protected String id;
Java支持多层继承(继承体系):Java中的所有类都直接或者间接的集成于java.lang.Object类
C继承B,B继承A,就会出现继承体系
多层继承出现的继承体系中,通常看父类中的功能,了解该体系的基本功能,建立子类对象,即可使用该体系功能。
定义继承需要注意:不要仅为了获取其他类中某个功能而去继承,类与类之间要有所属( “is a”)关系。
继承的出现提高了代码的复用性。继承的出现让类与类之间产生了关系,提供了多态的前提
将所有子类的共同属性放入父类,实现代码共享,避免重复,提高开发效率
可以使得修改扩展继承而来的实现比较简单
父类变,子类就必须变
继承破坏了封装,对于父类而言,它的实现细节对与子类来说都是透明的
继承是一种强耦合关系
public class Person {
public Person() {
System.out.println("Person....");
public class Student extends Person{
public Student() {
System.out.println(" studen....");
public static void main(String[] args) {
Student s1=new Student() ;
}
结论: . 上溯流程中先查找所有的父类,然后才从根类开始逐层调用构造器
建议的使用场景:把通用操作和方法放在父类中,将特殊的方法定义在子类中。
好处在于: 1、 避免代码重复。2、避免了人为因素导致的不- -致性