-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
黑马程序员—— 4,二维数组,面向对象,制作帮助文档,静态代码块,构造代码块,构造函数,单例设计模式
一:二维数组----》
格式:int[][] a=newint[5][9];
二维数组名字a,其中有5个一维数组,
每个一维数组里面有9个元素
一维数组的名称分别为:a[0],a[1],a[2],a[3],a[4]
如果只是System.out.println(a[0]);也只是会打印一维数组的哈希值
---------------------
格式2:int[][] a=new int[5][];
二维数组名字a,其中有5个一维数组,
每个一维数组默认初始化值null
可以再对这5个一维数组初始化
a[0]=new int[5];
a[1]=new int[6];
……
如果只是System.out.println(a[0]);也只是会打印null
如果只是System.out.println(a.length);也只是会打印二维数组的长度5
如果只是System.out.println(a[0].length);也只是会打印第一个一维数组长度
---------------------
格式3:int[][] a={{5,8,5},{8,8,3},{7}};
---------------------
int[][] y;int y[][];int[] y[];三种都是二维数组的写法
其中int[] x,y[]的意思是int[] x;int[] y[];
二:面向对象----》
面向对象是一种思维,将功能封装进对象,强调了具备功能的对象,是基于面向过程的。
面向对象的三个特征:
1,封装:隐藏对象属性和细节,对外提供公共的访问方式。
2,继承:从父类中获得方法和变量。
3,多态:事物的多种描述方式。
类:对事物的描述。 对象:实实在在的事物个体。
类中的成员就是属性和行为,对应就是成员变量和成员方法。
成员变量与局部变量的区别:前者作用范围是这个类,存放在堆内存中;后者作用范围是函数中,存放在栈内存中。
class Cat //有一个猫类
{
int leg=4;//有四只脚
int eye=2;//两只眼睛
private int age;//年龄私有化,外面不能直接访问,内部被封装了
public void setage(int a)//设立一个公共访问方法来访问年龄
{
if(a>1)//还可以在里面加一些逻辑判断语句
age =a;
}
void run()
{
System.out.println("这只跑起来的猫有"+leg+"只腿,"+eye+"只眼睛");
}
}
class Lei
{
public static void main(String[] args)
{
Cata=new Cat();//a是类类型变量,
Catb=a;//b与a指向的是同一个对象
a.eye=5;
b.run();//打印的是“这只跑起来的猫有4只腿,5只眼睛"
newCat().run();//这是匿名对象的调用,
System.out.println("HelloWorld!");
}
}
对象的建立需要调用对应的构造函数,构造函数用于对象的初始化,一个类中没有自定义构造函数,系统会默认一个空参数的构造函数。
类名与构造函数名相同,构造函数只可以执行一次。
class Cat //猫类
{
private String name;
private int age;
private int leg;
{
System.out.println("Hello 这是构造代码块!");//这是构造代码块,构造代码块只执行一次,给所有对象进行初始化,而且还是优先于构造函数,每一次新建一个对象,就要执行一次构造代码块
}
Cat()//建立构造函数
{
System.out.println("这只猫的名字"+name+";年龄"+age+";有"+leg+"只脚");
}
Cat(Stringna)//可以有多个构造函数,但是参数列表要不一样
{
name=na;
System.out.println("这只猫的名字"+name+";年龄"+age+";有"+leg+"只脚");
}
Cat(String na, int x)
{
name=na;
age=x;
System.out.println("这只猫的名字"+name+";年龄"+age+";有"+leg+"只脚");
}
}
class Gouzhao
{
public static void main(String[] args)//主函数
{
Cata=new Cat();//这句话会打印"这只猫的名字null;年龄0;有0只脚"
Cat b=new Cat("haha",12);
Catc=new Cat("niouniou");
System.out.println("HelloWorld!");
}
}
编译运行结果图1
图1
this的应用:
class Cat
{
private String name;
private int age;
private int leg;
{
System.out.println("Hello 这是构造代码块!");//这是构造代码块
}
Cat()//建立构造函数
{
System.out.println("这只猫的名字"+name+";年龄"+age+";有"+leg+"只脚");
}
Cat(Stringname)//可以有多个构造函数,但是参数列表要不一样
{
this();//构造函数之间调用构造函数用this,而且必须放在第一行,因为初始化要先执行
this.name=name;//this表示函数所属对象的引用,哪个对象在调用this所在的函数,this就表示哪个对象
}
Cat(String na, int x)
{
name=na;
age=x;
System.out.println("这只猫的名字"+name+";年龄"+age+";有"+leg+"只脚");
}
}
class Gouzhao
{
public static void main(String[] args)
{
Cata=new Cat();
Cat b=new Cat("haha",12);
Catc=new Cat("niouniou");
System.out.println("HelloWorld!");
}
}
Continue表示跳出本次循环,进入下次循环。
Break表示结束。
/*
break的用法
*/
class Forlizi2
{
public static void main(String[] args)
{
ints=0;
w: for(int x=1; x<=9;x++)
{
z:for(inty=1;y<x+1;y++)
{
s=x*y;
System.out.print(x+"*"+y+"="+s+";"+"\t");
break z ;//结束z的循环,而break w表示结束w的循环
}
System.out.println();
}
System.out.println("HelloWorld!");
}
}
static静态:
1,修饰的是类中的成员变量或者成员方法。
2,随着类的加载而加载;静态先存在,对象后存在。
3,被对象共享
4,可以直接被类名调用
5,静态方法只可以访问静态成员,静态方法中不可以定义this和super这些关键字
class Cat
{
static String zhongzu ="猫";//静态成员变量,类变量,
//随着类的加载而放在方法区
Stringname;//成员变量,实例变量,随着对象建立放在堆内存
public void show()
{
System.out.println("名字"+name+";种族"+zhongzu);
}
public static void hehe()
{
//this.show();静态方法无法应用非静态成员
}
}
class jingtai
{
public static void main(String[] args)
{
Cat a=new Cat();
System.out.println(Cat.zhongzu);
// 可以直接被类名调用,类名.静态成员,打印出来的是“猫”
}
}
小知识点:在cmd命令中,cd是前进,而cd..是后退。
以下是一道例题:
/*
这个工具类放在e:\ceshi
然后在此目录下生成Gongjulei的class文件
*/
class Gongjulei
{
public static int getmax(int[] args)
{
int max=0;
for(inta=1;a<args.length; a++ )
{
if(args[a]> args[max] )
max=a;
}
return args[max];
}
}
//而以下这个类
class lianxi //这个类放在e:\JAVAwenjian
{
public static void main(String[] args)
{
int[] k={10,4,25,8,16,34,47};
int shuchu=Gongjulei.getmax(k);//静态修饰可以直接用类名调用
System.out.println(shuchu);
}
}
以上的Gongjulei与lianxi这两个类都不在同一个路径中,所以在DOS窗口中设置class路径;再编译与运行就可以成功了。如图2所示。
图2
图2中的set classpath= .;\ceshi 表示的是先在当前路径下寻找class文件,再在e:\ceshi 中寻找class文件。
————————————————分割——————
三:帮助文档制作javadoc----》
/*
这个工具类放在e:\ceshi
然后在此目录下生成Gongjulei的class文件
*/
/**
这是一个对数组操作的工具类,该类中只有提供类获取int型数组最大值的功能
@author mo
@version V1.1
*/
public class Gongjulei //想要生成帮助文档,该类前面要加public
{
/**
获取int型数组最大值
@paramargs 接受一个int型数组
@return返回该数组中最大值
*/
public static int getmax(int[] args)
{
int max=0;
for(inta=1;a<args.length; a++ )
{
if(args[a]> args[max] )
max=a;
}
return args[max];
}
}
图3
如图3所示,在DOS窗口中输入javadoc -d jdwenjian –author -version Gongjulei.java再按回车键就可以建立帮助文档了。
其中-d表示地址,原地址目录下没有jdwenjian就会自动生成一个jdwenjian的文件夹,-author表示作者,-version表示版本。如图4所示。
图4
四:静态代码块,构造代码块,构造函数-----》
静态代码块:静态代码块随着类的加载而执行,只是执行一次。
Static
{
// 执行语句;
}
以下是一个很好的例子
class jintai1
{
static
{
System.out.println("人与神的斗争");
}
}
class jingtailizi
{
static//静态代码块优先于主函数执行
{
System.out.println("我是神");
}
public static void main(String[] args)
{
new jintai1();
new jintai1();//由于第一次加载了jintai1类而运行了静态代码块,所以,第二次建立对象就不会运行静态代码块了
System.out.println("HelloWorld!");
}
static//静态代码块优先于主函数执行
{
System.out.println("我是人");
}
}
编译运行结果如图5所示
图5
可以总结出:主函数所在的类的静态代码块先执行,被调用的类的静态代码块后执行。
构造代码块:没有加static关键字的代码块,每一次建立对象都会被调用,而且优先于构造函数执行。
三者之间的区别:代码块给对象初始化,构造函数可以给成员变量初始化,静态代码块给类初始化
Per p= new Per(“lisi”,12);
在这一句话的执行顺序是:
1,先是new要调用到Per的类文件,把Per的类文件加载到内存
2,接着,执行静态代码块,在堆内存中分配空间
3,建立对象属性
4,默认初始化,
5,显示初始化,
6,构造代码块初始化,
7,构造函数初始化,
8,内存地址赋值给栈内存中的p变2量。
/*
单例设计模式的简介
对同一个对象进行操作
*/
class Danli//饿汉式单例设计模式,该类进入内存就建立对象
{
privateDanli(){} //禁止外部建立对象
privatestatic Danli a=new Danli();//内部建立一个私有的静态对象
publicstatic Danli getdanli()//设置一个公共方法给外部访问
{
return a;//返回一个内部建立的对象
}
}
class Danli2//懒汉式单例设计模式,该类进入内存时对象还不存在
{
private Danli2(){} //禁止外部建立对象
private static Danli2 a=null;//a的指向为空
public static Danli2 getdanli()//设置一个公共方法给外部访问
{
if(a==null)
a=new Danli2();//方法被调用时,对象才被初始化
return a;//返回一个内部建立的对象
}
}
class Danlisheji
{
publicstatic void main(String[] args)
{
Danli aa= Danli.getdanli();//因为是静态的,直接用类名调用
Danli bb= Danli.getdanli();//aa与bb指向的是同一个对象
System.out.println("Hello World!");
}
}
/*
但是,懒汉式有一个很大的问题,就是
class Danli2//懒汉式单例设计模式,该类进入内存时对象还不存在
{
private Danli2(){} //禁止外部建立对象
private static Danli2 a=null;//a的指向为空
public static Danli2 getdanli()//设置一个公共方法给外部访问
{
if(a==null)
// ——》A程序执行到这里的时候,CPU切换到其他程序
// ——》B程序执行到这里的时候,CPU切换到其他程序
//接着A程序再回到这里执行下去的时候就会建立一个对象
//接着B程序再回到这里执行下去的时候就也会建立一个对象
//但是这样的话,堆中就会有两个对象,这个不符合单例设计模式的对象唯一性的规范
a=new Danli2();//方法被调用时,对象才被初始化
return a;//返回一个内部建立的对象
}
}
//为了订正这个问题可以用以下方式订正
class Danli2//懒汉式单例设计模式,该类进入内存时对象还不存在
{
private Danli2(){} //禁止外部建立对象
private static Danli2 a=null;//a的指向为空
public static synchronized Danli2 getdanli()//设置一个公共方法给外部访问
//其中的synchronized设定了只有当一个程序执行完了之后第二个程序才可以执行这个方法
{
if(a==null)
a=new Danli2();//方法被调用时,对象才被初始化
return a;//返回一个内部建立的对象
}
}
/*
或者是用下面改进的方式来修正,可是下面的修正方式累赘,编程时候还是建议使用饿汉式单例设计模式
*/
class Danli2//懒汉式单例设计模式,该类进入内存时对象还不存在
{
private Danli2(){} //禁止外部建立对象
private static Danli2 a=null;//a的指向为空
public static Danli2 getdanli()//设置一个公共方法给外部访问
{
if(a==null)
{
synchronized(Danli2.class)
/*
synchronized的作用就相当于一个锁,那个程序先进来就可以拿到锁匙,
等先进来的程序执行完之后第二个程序才可以进来
*/
{
if(a==null)
/*
为什么会这里还有一个if(a==null)的判断呢?
因为A程序进来执行完之后,B程序也可以进来这里,
如果没有这个判断B程序也会建立一个对象,这就不符合单例设计的规范
加上这个判断之后,B程序进来就会判断,此时的a已经指向了对象
所以,B程序就直接返回a,
这样的话建立的对象就只有A程序建立的唯一一个
*/
a =new Danli2();//方法被调用时,对象才被初始化
}
}
return a;//返回一个内部建立的对象
}
}
*/
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------