类的初始化过程
Student s = new Student();在内存中做了哪些事情?
加载Student.class文件进内存
在栈内存为s开辟空间
在堆内存为学生对象开辟空间
对学生对象的成员变量进行默认初始化
对学生对象的成员变量进行显示初始化
通过构造方法对学生对象的成员变量赋值
学生对象初始化完毕,把对象地址赋值给s变量
面向对象练习
定义一个类Demo,其中定义一个求两个数据和的方法,定义一个测试了Test,进行测试。
/*
定义一个类Demo,其中定义一个求两个数据和的方法,
定义一个测试了Test,进行测试。
变量什么时候定义为成员变量:
如果这个变量是用来描述这个类的信息的,那么,该变量就应该定义为成员变量。
变量到底定义在哪里好呢?
变量的范围是越小越好。因为能及时的被回收。
*/
//方式1
/*
class Demo {
public int sum() {
int a = 10;
int b = 20;
int c = a + b;
return c;
}
}
*/
//方式1满足了我们的要求,但是不好。
//因为参与操作的数据现在是固定的。
//方式2
/*
class Demo {
public int sum(int a,int b) {
return a + b;
}
}
*/
//方式2可以满足我们的要求,但是呢我们学习过来面向对象的思想。
//我就再想,a,b可不可以定义为成员变量呢?
//如果可以,我们再改进一版
class Demo {
int a;
int b;
public int sum() {
return a + b;
}
}
//虽然这种方式可以,并且好像是符合了面向对象的思想。
//但是不好。
//因为我们曾经说过:类是一组相关的属性和行为的集合。
//并且类是通过事物转换过来的
//而类中的成员变量就是事物的属性
//属性是用来描述事物的
//同理:成员变量其实是用来描述类的。
//测试类
class Test {
public static void main(String[] args) {
//创建对象
//方式1测试
/*
Demo d = new Demo();
System.out.println(d.sum());
*/
//方式2测试
/*
Demo d = new Demo();
int a = 10;
int b = 20;
System.out.println(d.sum(a,b));
*/
//方式3测试
Demo d = new Demo();
d.a = 10;
d.b = 20;
System.out.println(d.sum());
}
}
定义一个长方形类,定义 求周长和面积的方法,然后定义一个测试了Test2,进行测试。
/*
定义一个长方形类,定义 求周长和面积的方法,
然后定义一个测试了Test2,进行测试。
长方形的类:
成员变量:
长,宽
成员方法:
求周长:(长+宽)*2;
求面积:长*宽
注意:
import必须出现在所有的class前面。
*/
import java.util.Scanner;
class ChangFangXing {
//长方形的长
private int length;
//长方形的宽
private int width;
public ChangFangXing(){}
//仅仅提供setXxx()即可
public void setLength(int length) {
this.length = length;
}
public void setWidth(int width) {
this.width = width;
}
//求周长
public int getZhouChang() {
return (length + width) * 2;
}
//求面积
public int getArea() {
return length * width;
}
}
class Test2 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入长方形的长:");
int length = sc.nextInt();
System.out.println("请输入长方形的宽:");
int width = sc.nextInt();
//创建对象
ChangFangXing cfx = new ChangFangXing();
//先给成员变量赋值
cfx.setLength(length);
cfx.setWidth(width);
System.out.println("周长是:"+cfx.getZhouChang());
System.out.println("面积是:"+cfx.getArea());
}
}
定义一个员工类,自己分析出几个成员,然后给出成员变量,构造方法,getXxx()/setXxx()方法,以及一个显示所有成员信息的方法。并测试。
/*
需求:
定义一个员工类,自己分析出几个成员,
然后给出成员变量,构造方法,getXxx()/setXxx()方法,
以及一个显示所有成员信息的方法。并测试。
分析:
员工
成员变量:
员工编号,姓名,年龄
构造方法:
无参构造方法
成员方法:
getXxx()/setXxx()
show();
*/
class Employee {
//员工编号
private String employeeId;
//姓名
private String name;
//年龄
private int age;
//构造方法
public Employee() {}
//getXxx()/setXxx()
public String getEmployeeId() {
return employeeId;
}
public void setEmployeeId(String employeeId) {
this.employeeId = employeeId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//显示所有成员信息的方法
public void show() {
System.out.println("员工编号是:"+employeeId+"的这个人是:"+name+"的年龄是:"+age);
}
}
class EmployeeTest {
public static void main(String[] args) {
//创建对象
Employee e = new Employee();
//给成员变量赋值
e.setEmployeeId("czbk9527");
e.setName("唐伯虎");
e.setAge(18);
//获取数据
//System.out.println(e.getEmployeeId()+"---"+e.getName()+"---"+e.getAge());
//我们在Employee类中定义了一个show方法。所以,我们改进一下,使用show方法
e.show();
}
}
定义一个类MyMath,提供基本的加减乘除功能,然后进行测试。
/*
定义一个类MyMath,提供基本的加减乘除功能,然后进行测试。
*/
import java.util.Scanner;
class MyMath {
//加法功能
public int add(int a,int b) {
return a + b;
}
//减法功能
public int sub(int a,int b) {
return a - b;
}
//乘法功能
public int mul(int a,int b){
return a * b;
}
//除法功能
public int div(int a,int b) {
return a / b;
}
}
//测试类
class MyMathTest {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个操作数:");
int firstNumber = sc.nextInt();
System.out.println("请输入第二个操作数:");
int secondNumber = sc.nextInt();
//创建MyMath对象,并使用
MyMath mm = new MyMath();
System.out.println("加法结果:"+mm.add(firstNumber,secondNumber));
System.out.println("减法结果:"+mm.sub(firstNumber,secondNumber));
System.out.println("乘法结果:"+mm.mul(firstNumber,secondNumber));
System.out.println("除法结果:"+mm.div(firstNumber,secondNumber));
}
}
static关键字
可以修饰成员变量和成员方法
static关键字特点
随着类的加载而加载
优先于对象存在
被类的所有对象共享
这也是我们判断是否使用静态关键字的条件
可以通过类名调用
static关键字注意事项
在静态方法中是没有this关键字的
静态方法只能访问静态的成员变量和静态的成员方法
/*
定义一个人类
姓名和年龄都是变化的,这个我能接收,因为每个人的姓名和年龄是不同的。
但是,我们现在选取的几个人都是中国人,他们的国籍是一样的。
一样的国籍,我每次创建对象,在堆内存都要开辟这样的空间,
我就觉得有点浪费了。怎么办呢?
针对多个对象有共同的这样的成员变量值的时候,
Java就提高了一个关键字来修饰:static。
*/
class Person {
//姓名
String name;
//年龄
int age;
//国籍
//String country;
static String country;
public Person(){}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public Person(String name,int age,String country) {
this.name = name;
this.age = age;
this.country = country;
}
public void show() {
System.out.println("姓名:"+name+",年龄:"+age+",国籍:"+country);
}
}
class PersonDemo {
public static void main(String[] args) {
//创建对象1
Person p1 = new Person("邓丽君",16,"中国");
p1.show();
//创建对象2
//Person p2 = new Person("杨幂",22,"中国");
//p2.show();
Person p2 = new Person("杨幂",22);
p2.show();
//创建对象3
//Person p3 = new Person("凤姐",20,"中国");
//p3.show();
Person p3 = new Person("凤姐",20);
p3.show();
p3.country = "美国";
p3.show();
p1.show();
p2.show();
}
}
案例二代码:
/*
static的特点:(它可以修饰成员变量,还可以修饰成员方法)
A:随着类的加载而加载
回想main方法。
B:优先于对象存在
C:被类的所有对象共享
举例:咱们班级的学生应该共用同一个班级编号。
其实这个特点也是在告诉我们什么时候使用静态?
如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
举例:
饮水机(用静态修饰)
水杯(不能用静态修饰)
D:可以通过类名调用
其实它本身也可以通过对象名调用。
推荐使用类名调用。
静态修饰的内容一般我们称其为:与类相关的,类成员
*/
class Student {
//非静态变量
int num = 10;
//静态变量
static int num2 = 20;
}
class StudentDemo {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.num);
System.out.println(Student.num2);
System.out.println(s.num2);
}
}
static关键字注意事项
/*
static关键字注意事项
A:在静态方法中是没有this关键字的
如何理解呢?
静态是随着类的加载而加载,this是随着对象的创建而存在。
静态比对象先存在。
B:静态方法只能访问静态的成员变量和静态的成员方法
静态方法:
成员变量:只能访问静态变量
成员方法:只能访问静态成员方法
非静态方法:
成员变量:可以是静态的,也可以是非静态的
成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
简单记:
静态只能访问静态。
*/
class Teacher {
public int num = 10;
public static int num2 = 20;
public void show() {
System.out.println(num);//隐含的告诉你访问的是成员变量
System.out.println(this.num);//明确的告诉你访问的是成员变量
System.out.println(num2);
//function();
//function2();
}
public static void method() {
//无法从静态上下文中引用非静态 变量 num
//System.out.println(num);
System.out.println(num2);
//无法从静态上下文中引用非静态 方法 function()
//function();
function2();
}
public void function() {
}
public static void function2() {
}
}
class TeacherDemo {
public static void main(String[] args) {
//创建对象
Teacher t = new Teacher();
t.show();
System.out.println("------------");
t.method();
}
}
静态变量和成员变量的区别
所属不同
静态变量属于类,所以也称为为类变量
成员变量属于对象,所以也称为实例变量(对象变量)
内存中位置不同
静态变量存储于方法区的静态区
成员变量存储于堆内存
内存出现时间不同
静态变量随着类的加载而加载,随着类的消失而消失
成员变量随着对象的创建而存在,随着对象的消失而消失
调用不同
静态变量可以通过类名调用,也可以通过对象调用
成员变量只能通过对象名调用
main方法是静态的
public static void main(String[] args) {}
public 被jvm调用,访问权限足够大。
static 被jvm调用,不用创建对象,直接类名访问
void被jvm调用,不需要给jvm返回值
main 一个通用的名称,虽然不是关键字,但是被jvm识别
String[] args以前用于接收键盘录入的
演示案例:
/*
main方法的格式讲解:
public static void main(String[] args) {...}
public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。
static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。
void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。
main:是一个常见的方法入口。我见过的语言都是以main作为入口。
String[] args:这是一个字符串数组。值去哪里了?
这个东西到底有什么用啊?怎么给值啊?
这个东西早期是为了接收键盘录入的数据的。
格式是:
java MainDemo hello world java
*/
class MainDemo {
public static void main(String[] args) {
//System.out.println(args); //[Ljava.lang.String;@175078b
//System.out.println(args.length); //0
//System.out.println(args[0]); //ArrayIndexOutOfBoundsException
//接收数据后
System.out.println(args);
System.out.println(args.length);
//System.out.println(args[0]);
for(int x=0; x<args.length; x++) {
System.out.println(args[x]);
}
}
}
制作帮助文档
制作工具类
ArrayTools
制作帮助文档(API)
javadoc -d目录 -author -version ArrayTool.java
/*
我想要对数组进行操作
在同一个文件夹下,类定义在两个文件中和定义在一个文件中其实一样的。
*/
class ArrayDemo {
public static void main(String[] args) {
//定义数组
int[] arr = {28,55,37,46,19};
//需求:遍历数组
/*
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
*/
//如果我有多个数组都要进行遍历,那么,代码的重复度就很高
//如何改进呢?用方法改进
//调用
//静态方法
//printArray(arr);
//非静态方法
//ArrayDemo ad = new ArrayDemo();
//ad.printArray(arr);
//测试类的作用:创建其他类的对象,调用其他类的功能。
//而我们现在的操作是跟数组相关的,所以,你应该把这些操作定义到数组操作类中
//定义一个数组的操作类
//有了数组操作类之后的调用
//ArrayTool at = new ArrayTool();
//at.printArray(arr);
//方法改进为静态后,就可以直接通过类名调用
ArrayTool.printArray(arr);
}
/*
public static void printArray(int[] arr) {
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
}
*/
//假设该方法不是静态的
/*
public void printArray(int[] arr) {
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
}
*/
}
class ArrayTool {
//把构造方法私有,外界就不能在创建对象了
private ArrayTool(){}
public static void printArray(int[] arr) {
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
}
}
版本二
http://www.cnblogs.com/hnrainll/archive/2011/10/11/2206804.html API文档
/**
*这是针对数组进行操作的工具类
*@author 张长志
*@version V.1
*/
public class ArrayTool {
//把构造方法私有,外界就不能在创建对象了
/**
*这是私有构造
*/
private ArrayTool(){}
/**
*这是遍历数组的方法,遍历后的格式是:[元素1,元素2,元素3, ...]
*@param arr这是要被遍历的数组
*/
public static void printArray(int[] arr) {
System.out.print("[");
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) {
System.out.println(arr[x]+"]");
}else {
System.out.print(arr[x]+", ");
}
}
}
/**
*这是获取数组中最大值的方法
*@param arr这是要获取最大值的数组
*@return 返回数组中的最大值
*/
public static int getMax(int[] arr) {
int max = arr[0];
for(int x=1; x<arr.length; x++) {
if(arr[x] > max) {
max = arr[x];
}
}
return max;
}
/**
*获取指定元素在数组中第一次出现的索引,如果元素不存在,就返回-1
*@param arr被查找的数组
*@param value要查找的元素
*@return 返回元素在数组中的索引,如果不存在,返回-1
*/
public static int getIndex(int[] arr,int value) {
int index = -1;
for(int x=0; x<arr.length; x++) {
if(arr[x] == value) {
index = x;
break;
}
}
return index;
}
}
/*
我想要对数组进行操作
如何制作一个说明书呢?
A:写一个工具类
B:对这个类加入文档注释
怎么加呢?
加些什么东西呢?
C:用工具解析文档注释
javadoc工具
D:格式
javadoc -d 目录 -author -version ArrayTool.java
目录:就可以写一个文件夹的路径
制作帮助文档出错:
找不到可以文档化的公共或受保护的类:告诉我们类的权限不够
*/
class ArrayDemo {
public static void main(String[] args) {
//定义数组
int[] arr = {28,55,37,46,19};
//遍历
ArrayTool.printArray(arr);
//获取最值
int max = ArrayTool.getMax(arr);
System.out.println("max:"+max);
//获取55的索引值
int index = ArrayTool.getIndex(arr,55);
System.out.println("index:"+index);
}
}
API制作过程
javadoc -d目录 -author -version ArrayTool.java
如何使用文档
1:打开帮助文档
2:点击显示,找到索引,看到输入框
3:知道你要找谁?以Scanner举例
4:在输入框里面输入Scanner,然后回车
5:看包
java.lang包下的类不需要导入,其他的全部需要导入。
要导入:
java.util.Scanner
6:再简单的看看类的解释和说明,别忘了看看该类的版本
7:看类的结构
成员变量字段摘要
构造方法构造方法摘要
成员方法方法摘要
8:学习构造方法
A:有构造方法就创建对象
B:没有构造方法成员可能都是静态的
9:看成员方法
A:左边
是否静态:如果静态,可以通过类名调用
返回值类型:人家返回什么,你就用什么接收。
B:右边
看方法名:方法名称不要写错
参数列表:人家要什么,你就给什么;人家要几个,你就给几个
通过API学习Math类
Math类概述
Math包含用于执行基本数学运算的方法
Math类特点
没有构造方法,因为成员都是静态的
Math类讲解一个方法
获取随机数
获取1-100之间的随机数
案例:
/*
Math:类包含用于执行基本数学运算的方法
由于Math类在java.lang包下,所以不需要导包。
特点:
没有构造方法,因为它的成员全部是静态的。
掌握一个方法:
获取随机数
public static double random():返回带正号的 double值,该值大于等于 0.0且小于 1.0。
*/
class MathDemo {
public static void main(String[] args) {
//获取一个随机数
//double d = Math.random();
//System.out.println(d);
//需求:我要获取一个1-100之间的随机数,肿么办?
for(int x=0; x<100; x++) {
int number = (int)(Math.random()*100)+1;
System.out.println(number);
}
}
}
案例:
猜数字小游戏
/*
猜数字小游戏(数据在1-100之间)
分析:
A:程序产生一个随机数。(被猜的)
B:键盘录入数据。(你猜的)
C:把你猜的和被猜的进行比较
a:大了
b:小了
c:猜中了
D:给出多次猜的机会,猜中就结束。
while()循环,猜中就break
*/
import java.util.Scanner;
class GuessNumber {
public static void main(String[] args) {
//程序产生一个随机数。(被猜的)
int number = (int)(Math.random()*100)+1;
//System.out.println(number);
//给出多次猜的机会,猜中就结束。
while(true) {
//键盘录入数据。(你猜的)
Scanner sc = new Scanner(System.in);
System.out.println("请输入你要猜的数据(1-100):");
int guessNumber = sc.nextInt();
//把你猜的和被猜的进行比较
if(guessNumber > number) {
System.out.println("你猜的数据"+guessNumber+"大了");
}else if(guessNumber < number) {
System.out.println("你猜的数据"+guessNumber+"小了");
}else {
System.out.println("恭喜你,猜中了");
break;
}
}
}
}
代码块
代码块
在Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块
局部代码块
在方法中出现;限定变量生命周期,及早释放,提高内存利用率
构造代码块
在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
静态代码块 在类中方法外出现,加了static修饰
在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且值执行一次。
代码:
/*
代码块:在Java中,使用{}括起来的代码被称为代码块。
根据其位置和声明的不同,可以分为
局部代码块:局部位置,用于限定变量的生命周期。
构造代码块:在类中的成员位置,用{}括起来的代码。每次调用构造方法执行前,都会先执行构造代码块。
作用:可以把多个构造方法中的共同代码放到一起,对对象进行初始化。
静态代码块:在类中的成员位置,用{}括起来的代码,只不过它用static修饰了。
作用:一般是对类进行初始化。
面试题?
静态代码块,构造代码块,构造方法的执行顺序?
静态代码块 -- 构造代码块 --构造方法
静态代码块:只执行一次
构造代码块:每次调用构造方法都执行
*/
class Code {
static {
int a = 1000;
System.out.println(a);
}
//构造代码块
{
int x = 100;
System.out.println(x);
}
//构造方法
public Code(){
System.out.println("code");
}
//构造方法
public Code(int a){
System.out.println("code");
}
//构造代码块
{
int y = 200;
System.out.println(y);
}
//静态代码块
static {
int b = 2000;
System.out.println(b);
}
}
class CodeDemo {
public static void main(String[] args) {
//局部代码块
{
int x = 10;
System.out.println(x);
}
//找不到符号
//System.out.println(x);
{
int y = 20;
System.out.println(y);
}
System.out.println("---------------");
Code c = new Code();
System.out.println("---------------");
Code c2 = new Code();
System.out.println("---------------");
Code c3 = new Code(1);
}
}
面试题看代码说结果
/*
代码块:在Java中,使用{}括起来的代码被称为代码块。
根据其位置和声明的不同,可以分为
局部代码块:局部位置,用于限定变量的生命周期。
构造代码块:在类中的成员位置,用{}括起来的代码。每次调用构造方法执行前,都会先执行构造代码块。
作用:可以把多个构造方法中的共同代码放到一起,对对象进行初始化。
静态代码块:在类中的成员位置,用{}括起来的代码,只不过它用static修饰了。
作用:一般是对类进行初始化。
面试题?
静态代码块,构造代码块,构造方法的执行顺序?
静态代码块 -- 构造代码块 --构造方法
静态代码块:只执行一次
构造代码块:每次调用构造方法都执行
*/
class Code {
static {
int a = 1000;
System.out.println(a);
}
//构造代码块
{
int x = 100;
System.out.println(x);
}
//构造方法
public Code(){
System.out.println("code");
}
//构造方法
public Code(int a){
System.out.println("code");
}
//构造代码块
{
int y = 200;
System.out.println(y);
}
//静态代码块
static {
int b = 2000;
System.out.println(b);
}
}
class CodeDemo {
public static void main(String[] args) {
//局部代码块
{
int x = 10;
System.out.println(x);
}
//找不到符号
//System.out.println(x);
{
int y = 20;
System.out.println(y);
}
System.out.println("---------------");
Code c = new Code();
System.out.println("---------------");
Code c2 = new Code();
System.out.println("---------------");
Code c3 = new Code(1);
}
}