无限递归(死归)
求n!把问题分解成求n*(n-1)!
特点:可以把问题分解成子问题
思路:告诉计算机做什么。
static方法与非static方法之间的调用关系,有以下四种:
1、非static方法调用非static方法,直接通过方法名调用
2、static方法调用static方法,直接通过方法名调用
3、非static方法调用static方法,直接通过方法名调用
4、static方法调用非static方法,通过类对象来调用
面向对象(上)
(一)
3条主线:
(1)类和类的的成员的研究
属性
方法
构造器
代码块
内部类
(2)三大特征
封装
继承
多态
(3)其他关键字
this super package important 。。。。。
思路:
如果有现成的对象 直接拿来用,如果没有,现制造一个对象来使用
类:对现实世界事物的描述:
对象:它是类的实体(个体)
实例i,就是对象。
成员:意味着直接相互访问
面向对象程序的重点:类的设计
属性:对应类中的成员变量(描述事物的特征)
方法:对应类中的成员方法(描述对象的行为)
的语法格式:
修饰符 class 类名{
属性声明;
方法声明 ;
}
说明:修饰符public:类可以被访问
类的正文要要用{}括起来
Teacher t= new teacher();右面是以个创建对象的操作,必须使用new操作符。作用是根据类模板制造一个对象。
t是Teacher类型的引用变 量
成员和成员之间互为成员
成员之间直接相互访问
即使是同一个类对象,他们之间也是相互独立的,各自拥有一套属性值。
属性的隐式初始化为0;
public是公共的,private是私有的
set 有参无返回,get 无参有返回
封装:private私有化成员属性,提供公开public的getter/setter
Setter:赋值 Getter:取值,在哪儿用:在构造方法中初始化属性值的用!!!!!或者对象名.set/get()进行使用!!!
好处:隐藏内部实现细节,保证代码的安全,同时也可以提升数据的安全性
访问修饰符,从访问的范围由小及大依次是:private default(当什么都不写默认就是这个) protected public
访问修饰符的作用:可以修饰类、接口、属性和方法。通常可以通过访问修饰符来改变所修饰对象的可访问范围。
二
垃圾对象:没有引用指向的对象
如何清理:把相应空间重新标记为可用空间
面向对象:关注具有功能的对象
面向对象的重点是类的设计
面向对象在解决问题时,必须使用对象了来完成任务,提高复封装:成员私有化 保护数据的合法性
this表示当前对象,他的作用是限定的对象成员,解决局部变量和对象那属性重名的问题
以static修饰的为类变量
不以static修饰的变量为实例变量
使用new+构造器创建一个对象:
使用对象.对象成员的方式访问对象成员(包括属性和方法):
构造方法在创建对象时进行初始化工作
构造器(构造方法)的特征:
(1)它具有与类相同的名称(方法名和类名相同)这是唯一允许首字母大写的方法名
(2)它不能声明返回值类型,即使void也不允许;
(3)不能被static final synchronized abstract native 修饰,不能有return返回值
(4)构造器不可以像普通方法一样随意调用
如果类中没有写任何构造器,编译器会自动添加一个构造器,这个构造器称为确省构造器,特点是修饰符和类一致,无参,无语句。
如果类中 提供了构造器,编译器就不会添加任何构造器
构造器也可以重载,只需要参数不同即可
代码示例
public class ConstructorOverload {
public String name;
public int count;
/**
* 提供无参数的构造器
*/
public ConstructorOverload() {
}
/**
* 提供一个参数的构造器,对构造器返回的对象进行初始化
*
* @param name 名称
*/
public ConstructorOverload(String name) {
this.name = name;
}
/**
* 提供两个参数的构造器,对构造器返回的对象进行初始化
*
* @param name 名称
* @param count 数量
*/
public ConstructorOverload(String name, int count) {
this.name = name;
this.count = count;
}
public static void main(String[] args) {
// 通过无参数的构造器创建 ConstructorOverload 对象
ConstructorOverload con1 = new ConstructorOverload();
// 通过一个参数的构造器创建 ConstructorOverload 对象
ConstructorOverload con2 = new ConstructorOverload("西瓜");
// 通过两个参数构造器创建 ConstructorOverload 对象
ConstructorOverload con3 = new ConstructorOverload("玉米", 100);
// 开始调用方法
System.out.println("名称:" + con1.name);
System.out.println("名称:" + con2.name);
System.out.println("名称:" + con3.name + "\t 数量:" + con3.count);
}
}
如果系统中包含多个构造器,其中一个构造器的执行体里完全包含另一个构造器的执行体,如下图所示:
从图中可以看出,构造器 B 完全包含了构造器 A 。对于这种完全包含的情况分两种:
方法之间:如果是两个方法之间存在这种关系,则可在方法 B 中直接调用方法 A 。
构造器之间:构造器不能直接被调用,构造器必须使用 new关键字来调用。但一旦使用 new 关键字来调用构造器,将会导致系统重新创建一个对象。
2.1、代码表示
为了在构造器 B 中调用构造器 A 中的初始化代码,又不会重新创建一个 Java 对象,可以使用 this 关键字来调用相应的构造器。下面代码实现了在一个构造器中,直接使用另一个构造器的初始化代码。
/**
* @author Administrator
*/
public class ConstructorInvoke {
public String name;
public int count;
public double weight;
/**
* 无参构造
*/
public ConstructorInvoke() {
}
/**
* 两个参数的构造器
*
* @param name 名称
* @param count 数量
*/
public ConstructorInvoke(String name, int count) {
this.name = name;
this.count = count;
}
/**
* 三个参数的构造器
*
* @param name 名称
* @param count 数量
* @param weight 重量
*/
public ConstructorInvoke(String name, int count, double weight) {
/*this.name = name;
this.count = count;*/
// 通过 this 调用另一个重载的构造器的初始化代码
this(name, count);
// 下面 this 引用该构造器正在初始化的 Java 对象
this.weight = weight;
}
public static void main(String[] args) {
ConstructorInvoke radish = new ConstructorInvoke("萝卜", 200, 2);
System.out.println("名称:" + radish.name + "\t数量:" + radish.count + "\t" + "重量" + radish.weight);
}
}
this(…)的调用必须放在第一行,效果就是当前构造器的其他代码晚于其他构造器的执行
构造器中一定有一个不是this(…)如果全是this(…)会无限递归
全参构造器:优点:创建对象一步到位,缺点:调用复杂
无参构造器:优点:调用简单 缺点:对象单调
对象传递有风险,本质是传递地址‘
创建对象的步骤:
永久区(方法区)
1) 在永久区中检查要创建的对象所属的类模板
2) 如果没有加载过, 则由类加载器加载类模板
3) 如果已经加载过了, 就不加载, 保证类模板只有一份
4) 依据类模板中所有属性的定义, 在GC区中开辟空间
5) 把此空间全部写0, 结果就是所有属性自动拥有缺省值
6) 属性如果有显式赋值, 执行显式赋值
7) 执行构造方法
8) 返回对象地址
类模板中包含了什么?
属性定义(修饰符,数据类型,属性名)
方法代码(静态的)
对象和属性的关系:对象拥有属性,属性隶属于对象
(三)
对象关联:一个对象拥有另一个对象,怎么拥有?把另一个对象作为我的属性即可
另外的对象一旦作为属性有麻烦
1)改造全参构造
2)改造一对get/set方法
3)改造say方法
对象 关联是通过构造器
JavaBean是Java写成的可重用组件
1)类是公共的
2)有公共无参构造器,在创建对象时方便
3)有属性,且有对应的get Set方法
package :将当前源文件中将来生成的.class文件放入指定的包目录结构;
package 必须放在源文件第一行,类外面,对当前源文件的所有类器作用
package 机构类型.机构名称.项目名称.模块名称;
一旦使用了package,有以下麻烦
1)编译麻烦,必须使用 -d 选项
javac 空格 -d 空格 目标目录 空格 源文件名列表
javac 空格 -d 空格 . 空格 源文件名列表
使用当前类 麻烦
如果在其他包的类中使用当前类,必须使用当前类的全限定类名(包名.子包名.类名)
不能在使用简单类名
import的作用是告诉编译器,当前类中用到的其他包的类图和去定位
important语句必须写在package后面,并且也在类外
important全限定类名;
一旦使用了important语句,当前源文件中就可以不用在使用全限定类名
important语句可以有多条,表示导入多个类
java.lang包是最常用的包,只要写程序100%用到,可以省略或全限定
除了java。lang包以外的其他包的使用必须导入或限定。
数组
一组相同数据类型数据的组合,数组中可以有多个元素,类型都相同,每个元素相当于数组对象的属性
数组中的元素可以使任何数据类型,包括基本数据类型和引用数据类型
数组属于引用类型,数组型数据是对象
声明:
数组的元素的数据类型[ ] 数组名;
创建:
new 数组的元素的数据类型[元素个数];
元素的访问:
首地址+偏移量
数组[偏移量]
偏移量叫做下表,或索引或脚表
数组定义的语法
type【】 arrayName