Java SE面向对象部分12面向对象基.docx
《Java SE面向对象部分12面向对象基.docx》由会员分享,可在线阅读,更多相关《Java SE面向对象部分12面向对象基.docx(28页珍藏版)》请在冰豆网上搜索。
JavaSE面向对象部分12面向对象基
JavaSE面向对象部分-12.面向对象基础(07)
上季内容回顾:
1、内部类
2、对象数组的使用
本季主要知识点:
本季要点:
static关键字的使用。
本季讲解了Java中static关键字的使用以及单态设计模式。
static的使用
设计一个类:
Person类,有name、age、city三个属性
classPerson
{
//为了方便,属性暂时不封装
Stringname;
intage;
//所在城市默认为南京
Stringcity="南京";
publicPerson(Stringname,intage)
{
this.name=name;
this.age=age;
}
publicStringgetInfo()
{
return"姓名:
"+name+",年龄:
"+age+",城市:
"+city;
}
};
publicclassDemo01
{
publicstaticvoidmain(Stringargs[])
{
Personp1=newPerson("张三",30);
Personp2=newPerson("李四",31);
Personp3=newPerson("王五",32);
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
}
};
先把内存结构图画出来
仔细观察,这三个对象的city属性的值都是南京,就好比说我现在所产生的人都是南京人。
那么这样的设计就会存在问题:
1、属性的内容重复存在,所有对象都有此属性
2、如果现在假设南京变为北京了,假设已经产生了100000个对象,则此时如果要修改其所在城市属性的内容,则肯定要修改100000遍
解决方法:
·所有的对象都共同指向同一个city属性是最好的,有一个对象将city属性修改了,则其他的也会影响。
此时就需要使用static标识city属性了。
classPerson
{
//为了方便,属性暂时不封装
Stringname;
intage;
//所在城市默认为南京
staticStringcity="南京";
publicPerson(Stringname,intage)
{
this.name=name;
this.age=age;
}
publicStringgetInfo()
{
return"姓名:
"+name+",年龄:
"+age+",城市:
"+city;
}
};
publicclassDemo02
{
publicstaticvoidmain(Stringargs[])
{
Personp1=newPerson("张三",30);
Personp2=newPerson("李四",31);
Personp3=newPerson("王五",32);
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
}
};
再来看下内存结构
加入static声明之后所有的static类型的属性都保存在了全局数据区之中,所有的对象都共同拥有同一个city属性了。
classPerson
{
//为了方便,属性暂时不封装
Stringname;
intage;
//所在城市默认为南京
staticStringcity="南京";
publicPerson(Stringname,intage)
{
this.name=name;
this.age=age;
}
publicStringgetInfo()
{
return"姓名:
"+name+",年龄:
"+age+",城市:
"+city;
}
};
publicclassDemo03
{
publicstaticvoidmain(Stringargs[])
{
Personp1=newPerson("张三",30);
Personp2=newPerson("李四",31);
Personp3=newPerson("王五",32);
System.out.println("----------修改city属性之前----------");
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
System.out.println("----------修改city属性之后----------");
//通过一个对象修改city属性值
p1.city="北京";
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
}
};
验证下效果
一个对象修改static属性之后,其他的所有对象都可以更改了。
但是以上的程序有一些不妥,一个城市改变是应该由某个人(某个对象)去做的吗?
应该是由对象的集合体去做,对象的集合体就是类,所以一般在访问static属性的时候都采用如下格式:
·类名称.static属性 这是最合理的。
classPerson
{
//为了方便,属性暂时不封装
Stringname;
intage;
//所在城市默认为南京
staticStringcity="南京";
publicPerson(Stringname,intage)
{
this.name=name;
this.age=age;
}
publicStringgetInfo()
{
return"姓名:
"+name+",年龄:
"+age+",城市:
"+city;
}
};
publicclassDemo04
{
publicstaticvoidmain(Stringargs[])
{
Personp1=newPerson("张三",30);
Personp2=newPerson("李四",31);
Personp3=newPerson("王五",32);
System.out.println("----------修改city属性之前----------");
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
System.out.println("----------修改city属性之后----------");
//通过一个对象修改city属性值
//最好是通过类名称去修改static属性,即static属性可以被类名称直接访问
Person.city="北京";
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
}
};
验证一下
有些时候也有人把static类型的属性称为类属性(类变量),因为可以直接由类名称进行访问。
既然static可以声明属性,则static也可以声明方法,使用static声明的方法称为类方法,也可以由类名称直接调用。
classPerson
{
//为了方便,属性暂时不封装
privateStringname;
privateintage;
//所在城市默认为南京
privatestaticStringcity="南京";
//只编写一个可以修改city的方法
publicstaticvoidsetCity(Stringcity)
{
this.city=city;
}
publicPerson(Stringname,intage)
{
this.name=name;
this.age=age;
}
publicStringgetInfo()
{
return"姓名:
"+name+",年龄:
"+age+",城市:
"+city;
}
};
publicclassDemo05
{
publicstaticvoidmain(Stringargs[])
{
Personp1=newPerson("张三",30);
Personp2=newPerson("李四",31);
Personp3=newPerson("王五",32);
System.out.println("----------修改city属性之前----------");
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
System.out.println("----------修改city属性之后----------");
//通过一个对象修改city属性值
//最好是通过类名称去修改static属性,即static属性可以被类名称直接访问
//Person.city="北京";
Person.setCity("无锡");
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
}
};
这样验证下有没问题哈~
classPerson
{
//为了方便,属性暂时不封装
privateStringname;
privateintage;
//所在城市默认为南京
privatestaticStringcity="南京";
//只编写一个可以修改city的方法
publicstaticvoidsetCity(Stringc)
{
//this是表示当前对象,static属性是绝对不能用this表示滴~
//因为static属性不绝对属于某一个对象
//this.city=city; ---->这是错误滴哈~~~
city=c;
}
publicPerson(Stringname,intage)
{
this.name=name;
this.age=age;
}
publicStringgetInfo()
{
return"姓名:
"+name+",年龄:
"+age+",城市:
"+city;
}
};
publicclassDemo06
{
publicstaticvoidmain(Stringargs[])
{
Personp1=newPerson("张三",30);
Personp2=newPerson("李四",31);
Personp3=newPerson("王五",32);
System.out.println("----------修改city属性之前----------");
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
System.out.println("----------修改city属性之后----------");
//通过一个对象修改city属性值
//最好是通过类名称去修改static属性,即static属性可以被类名称直接访问
//Person.city="北京";
//使用static声明的方法可以直接使用类名称调用
Person.setCity("无锡");
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
}
};
看下程序效果
Static使用的限制:
1、使用static声明的方法能否访问static声明的属性呢?
允许的
classDemo07
{
staticStringname="Michael";
publicstaticvoidfun()
{
System.out.println(name);
}
};
编译通过哈~
2、使用static方法能否访问非static声明的属性呢?
不允许的
classDemo08
{
Stringname="Michael";
publicstaticvoidfun()
{
System.out.println(name);
}
};
编译不能通过,说明是不允许滴~~~
3、使用非static方法能否访问static声明的属性呢?
允许的
classDemo09
{
staticStringname="Michael";
publicvoidfun()
{
System.out.println(name);
}
};
编译通过,说明是允许滴
4、使用非static能否访问非static声明的属性呢?
允许的
classDemo10
{
Stringname="Michael";
publicvoidfun()
{
System.out.println(name);
}
};
这个编译也通过,说明也是允许滴
Main方法调用其他方法的问题:
·之前讲解方法的时候给了一个限制:
如果一个方法想被主方法直接调用,则此方法声明时必须加上publicstatic才可以。
publicclassDemo11
{
publicstaticvoidmain(Stringargs[])
{
fun();
}
publicstaticvoidfun()
{
System.out.println("");
}
};
如果我们在fun()方法前没有加上static滴话,我们看下会报什么错误
publicclassDemo12
{
publicstaticvoidmain(Stringargs[])
{
fun();
}
publicvoidfun()
{
System.out.println("");
}
};
注意:
static类型的方法只能调用static类型的方法
publicclassDemo13
{
//static类型的方法只能调用static类型的方法
publicstaticvoidmain(Stringargs[])
{
//如果fun()方法前不加static,则只能这样调用
newDemo13().fun();
}
publicvoidfun()
{
System.out.println("");
}
};
程序执行正常
主方法的含义:
publicstaticvoidmain(Stringargs[])
理解main方法
Stringargs[]:
表示运行时的参数==>表示String类型的对象数组
publicclassDemo14
{
publicstaticvoidmain(Stringargs[])
{
for(inti=0;i {
System.out.println(args[i]);
}
}
};
我们发现没有内容输出哈,那我们在javacDemo14.java后面跟上几个数据哈,以空格分开
所有的参数会在命令后面加入空格的形式出现。
我们做个练习哈~
publicclassDemo15
{
publicstaticvoidmain(Stringargs[])
{
//必须输入两个参数
if(args.length!
=2)
{
//表示不是两个参数,则要退出系统
System.out.println("运行参数不正确,正确的格式为:
");
System.out.println("javaDemo15用户名密码");
System.exit
(1);
}
//之后的程序就表示肯定已经成功的输入了用户名和密码哈~~~
StringuserName=args[0];
StringuserPasswd=args[1];
//判断用户名是否为abc,密码是否为123哈~~~
//为什么现在要用字符串.equals去判断而不是用username调用equals哈~
//这样可以有效滴避免NullPointerException
if("abc".equals(userName)&&"123".equals(userPasswd))
{
System.out.println("欢迎访问哈~~~");
}
else
{
System.out.println("用户名和密码不正确哈~~~");
}
}
};
验证一下程序
解释:
为什么要把字符串放在前面比较
publicclassDemo16
{
publicstaticvoidmain(Stringargs[])
{
Stringstr="";
System.out.println(str.equals(""));
}
};
程序执行下,看下有没问题哈~
结果为true,没有出错哈,但是大家知道str是引用数据类型哈,如果str值为null空的话,就会出现问题。
publicclassDemo17
{
publicstaticvoidmain(Stringargs[])
{
Stringstr=null;
System.out.println(str.equals(""));
}
};
程序提示NullPointerException错误哈~
那我们现在把str和字符串交换下位置看下效果
publicclassDemo18
{
publicstaticvoidmain(Stringargs[])
{
Stringstr=null;
System.out.println("".equals(str));
}
};
字符串永远不会为空哈,所以不会报NullPointerException错误哈~
因此我们在开发中经常把字符串写在前面,然后调用equals方法进行比较哈,这样可以避免出现错误~~
Static的基本概念已经掌握清楚了,那么还可以在以下一种情况下使用:
·如果现在想统计一个类到底产生了多少个