java基础104M24.docx
《java基础104M24.docx》由会员分享,可在线阅读,更多相关《java基础104M24.docx(87页珍藏版)》请在冰豆网上搜索。
java基础104M24
Java基础
一、面向对象
1、类的定义
类:
具有相同功能和相同属性的一类事物的集合。
例子:
对人类进行描述
人:
属性:
姓名、年龄、性别
功能:
吃的功能、跑的功能,等等。
如何通过程序语言表述:
Person.java
classPerson{
Stringname;
intage;
Stringsex;
publicvoideat(){
System.out.println("吃。
");
}
publicvoidrun(){
System.out.println("跑。
");
}
}
编译:
javacPerson.java会生成一个对应的class文件:
Person.class
运行:
javaPerson注意:
该类运行时会报一个错误:
说明:
函数publicstaticvoidmain(String[]args);是程序的入口。
运用类时,虚拟机会自动调用该函数。
2、方法的调用
Person.java
classPerson{
publicvoidrun(){
System.out.println("跑。
");
}
publicstaticvoidmain(String[]args){
run();
}
}
编译:
javacPerson.java时报错:
分析错误原因:
main方法是一个被static修饰的方法,那么这样的方法就叫静态方法,而我们定义的run方法是一个没有被static修饰的方法,即不是静态方法。
意味着这两个方法不是同一级别的方法,所以在main方法中无法访问非静态方法run();
解决的办法:
1、将main方法改为非静态的,但是不行,因为该方法是系统默认定义的。
不能改。
2、只能改我们自定义的run方法。
将该方法改为静态的。
Person.java
classPerson{
publicstaticvoidrun(){
System.out.println("跑。
");
}
publicstaticvoidmain(String[]args){
run();
}
}
编译:
javacPerson.java生成了Person.class文件
运行:
javaPerson
3、Java中的包的定义
Java中不允许有“裸体类”,即类不能没有包的定义。
上面的Person类就是一个裸体类。
没有包的修饰。
应改为:
Person.java
packagecom.test;
publicclassPerson{
publicstaticvoidrun(){
System.out.println("跑。
");
}
publicstaticvoidmain(String[]args){
run();
}
}
关键字package是定义包的。
编译:
javacPerson.java同样生成了class文件
运行:
javaPerson程序报错了:
因为程序中类的名字多了包的约束了。
所以我们访问该类时,要以全路径访问,即包的完整路径加类的名称来访问类。
运行:
javacom.test.Person依然报错,说类找不到。
分析:
看javac有一个-d参数,表示类生成的存放路径。
从上图可以看出:
我们生成的类(Person.class)没有存放到com/test包中。
所以无法正常访问。
如何修改?
我们应重新编译源文件:
Person.java
编译:
javac–dD:
/test/srcPerson.java生成了类:
com.test.Person
查看类文件的生成情况:
打开com文件夹及其子文件夹test
运行:
javacom.test.Person
此时程序运行正常。
说明:
带了包的源文件在编译时,要带上类的生成路径。
即用-d参数来编译。
访问该类时,也要带上包类访问。
说明一个类的完整名称,要有包。
4、静态方法的调用
再编写一个测试类:
Test.java
packagecn.test2;
publicclassTest{
publicstaticvoidmain(String[]args){
//想调用Person类中的静态方法:
run()
run();//模仿在Person类的main方法中的调用方式调用。
}
}
编译:
javac–dD:
/test/srcTest.java报错。
分析错误原因:
因为我们想调用的run方法是com.test.Person类的。
所以我们不能直接像在Person类中一样来访问run方法,我们应该全名称类访问。
既是带是该方法所在的包的类来访问。
所以Test.java文件的内容应改为:
Test.java
packagecn.test2;
publicclassTest{
publicstaticvoidmain(String[]args){
//想调用Person类中的静态方法:
run()
//run();//错误,要全名称访问。
com.test.Person.run();
}
}
编译:
javac–d.Test.java生成Test的类,注意:
“.”是相对路径,既是当前路径,等同于“D:
/test/src”路径。
运行:
javacn.test2.Test
上面程序说明:
静态方法访问原则:
1、如果调用该静态方法的代码块和该方法在同一个类中,类名可以省略。
2、如果调用代码块和被调用方法不在同一个类中,且包也不同,那么必须在被调用方法前写上全路径,即”包名.类名.方法名”的形式访问。
5、访问权限控制语句的使用
public
protected
默认(不写)
private
所有类中都可以访问
不仅可以在同一个包中的类内访问,还可以在子类中访问
包访问权限
类访问权限
1、public权限
在整个系统中的任意类中都可以访问,该关键字可以修饰类,方法,属性。
修饰类的话,表示该类是一个公共类;修饰方法,表示该方法是公共方法,可以在任意类中使用,修饰属性表示该属性可以在任意类中访问。
Person.java
packagecom.test;
publicclassPerson{
publicstaticStringname="Personname.";
publicstaticvoidrun(){
System.out.println("跑。
");
}
publicstaticvoidmain(String[]args){
run();
}
}
Test.java
packagecn.test2;
publicclassTest{
publicstaticvoidmain(String[]args){
//想调用Person类中的静态方法:
run()
//run();//错误,要全名称访问。
com.test.Person.run();
Stringn=com.test.Person.name;
System.out.println(n);
}
}
注意:
当前我们编写的两个类,不是在相同的包中定义的。
我们想在Test中访问Person的公共属性和公共方法。
程序执行结果说明访问正常。
将上面的Person.java中的类修饰符public去掉。
然后编译并访问。
报错是:
“Exceptioninthread"main"java.lang.IllegalAccessError”
说明如果类不是公共的,即使它的属性和方法都是公共的,依然无法访问。
将Test.java的包改为和Person.java的包一样。
然后编译并运行。
程序能正常执行了。
由以上情况得出:
如果一个类中的属性和访问即使都是public修饰的,但是类不是public修饰的,那么这些属性和方法依然无法访问,要想访问,必须调用者和被调用者在相同的包中。
2、默认访问权限,就是不写任何访问修饰符
将上面程序中Person.java中的属性和方法的public修饰去掉,把类的修饰符加上public。
packagecom.test;
publicclassPerson{
staticStringname="Personname.";
staticvoidrun(){
System.out.println("跑。
");
}
publicstaticvoidmain(String[]args){
run();
}
}
编译person.java文件,并访问Test类,结果正常。
接着将Test.java的包改为:
cn.test2;
packagecn.test2;
publicclassTest{
publicstaticvoidmain(String[]args){
//想调用Person类中的静态方法:
run()
//run();//错误,要全名称访问。
com.test.Person.run();
Stringn=com.test.Person.name;
System.out.println(n);
}
}
编译Test.java文件,报错。
由以上情况说明:
默认不写的访问权限,最大不能出包。
一旦出包就无法访问了。
3、private访问权限
接着将person.java文件中的属性和方法的访问修饰符改为private;
packagecom.test;
publicclassPerson{
privatestaticStringname="Personname.";
privatestaticvoidrun(){
System.out.println("跑。
");
}
publicstaticvoidmain(String[]args){
run();
}
}
将Tess.java的包改为和Person.java的包一样。
packagecom.test;
publicclassTest{
publicstaticvoidmain(String[]args){
//想调用Person类中的静态方法:
run()
//run();//错误,要全名称访问。
com.test.Person.run();
Stringn=com.test.Person.name;
System.out.println(n);
}
}
编译报错:
说明:
private修饰的只能在类中访问。
4、protected访问权限
Person.java
packagecom.test;
publicclassPerson{
protectedstaticStringname="Personname.";
protectedstaticvoidrun(){
System.out.println("跑。
");
}
publicstaticvoidmain(String[]args){
run();
}
}
Test.java
packagecom.test;
publicclassTest{
publicstaticvoidmain(String[]args){
//想调用Person类中的静态方法:
run()
//run();//错误,要全名称访问。
com.test.Person.run();
Stringn=com.test.Person.name;
System.out.println(n);
}
}
可以访问。
将上面的Test.java的包改为:
cn.test2;
Test.java
packagecn.test2;
publicclassTest{
publicstaticvoidmain(String[]args){
//想调用Person类中的静态方法:
run()
//run();//错误,要全名称访问。
com.test.Person.run();
Stringn=com.test.Person.name;
System.out.println(n);
}
}
编译报错:
上面的程序说明:
如果两个类没有继承关系,且两个类不在同一个包中,那么protected的就无法跨包访问了。
注意:
protected的还可以在子类中访问,会在后面进一步介绍。
5、封装
1)封装的定义:
在java中主要指,类的成员变量私有化,然后通过getXXX和setXXX方法对成员变量进行读和写的操作。
以保证安全性。
我们可以在获取值或者改变值之前对方法调用者进行比如身份的验证,数据的合法验证等等操作。
这样做能保证数据的安全性。
6、方法的定义
1、方法的组成
方法:
[修饰符……]返回值类型方法名([形参列表]){方法体:
该方法要做的事情……}
2、例子
无参方法:
Test.java
packagecom.test;
publicclassTest{
publicstaticvoidprint(){
System.out.println("该方法是一个公共访问级别的静态方法,没有参数。
");
}
}
有参方法:
Test.java
packagecom.test;
publicclassTest{
publicstaticvoidprint(){
System.out.println("该方法是一个公共访问级别的静态方法,没有参数。
");
}
publicstaticintprint(intstart,intend){
intsum=0;
for(;start<=end;start++){
if(start%2==0){
sum+=start;
}
}
returnsum;
}
}
注意:
Test类中的两个方法的名字完全相同,但是可以共存,但是参数不同,这是方法的重载。
如果一个方法不返回任何值,那么该方法的定义处,要以void做为返回值类型出现,以满足方法定义的要求。
Void也是java中的一个关键字,表示空。
7、普通代码块
1、普通代码块的定义
在方法中出现的“{}”就叫普通代码块。
普通代码块中定义的变量的使用范围:
就是当前普通代码块。
出了该代码块就无法识别了。
2、例子
Test.java
packagecom.test;
publicclassTest{
publicstaticvoidmain(String[]args){
inti=9;
//inti=90;//变量的重复定义。
{
//inti=90;//变量的重复定义。
intj=90;
System.out.println("j="+j);//可以正常访问。
}
//下面不可以正常访问。
因为j的可视范围只在普通代码块中。
//System.out.println("j="+j);
intj=99;//这是可以的。
}
}
注意:
main方法中定义的变量的使用范围是从定义处到main方法结束,而普通代码块中定义的变量的可视范围从定义处到普通代码块结束处。
3、画内存图
该图是针对上面Test.java中main方法的内存图。
8、静态代码块
1、静态代码块的定义
在类的内部,方法的外部,被关键字static修饰的代码块就叫静态代码块。
Test1.java
packagecom.test;
publicclassTest1{
{
System.out.println("这是构造块,加载类时不会执行。
");
}
static{
System.out.println("这是静态代码块,加载类时会执行。
");
}
}
上面的程序说明:
静态代码块会被虚拟机自动调用,且是在main方法之前调用的。
构造代码块在加载类时不会被调用。
2、静态代码块的功能
静态代码块的主要功能是为静态变量初始化的。
Test1.java
packagecom.test;
publicclassTest1{
staticinti;//系统会为该变量默认初始化为0
static{
System.out.println("i="+i);
}
}
编译运行:
Test1.java将Test1.java修改。
packagecom.test;
publicclassTest1{
static{
System.out.println("i="+i);
}
staticinti;//系统会为该变量默认初始化为0
}
编译:
报错“非法向前引用”
Test1.java再次修改
packagecom.test;
publicclassTest1{
static{
//System.out.println("i="+i);
i=9;
System.out.println("静态代码块执行了。
");
}
staticinti;//系统会为该变量默认初始化为0
}
编译并运行:
由以上三个程序得出结论:
静态代码块就是对静态变量进行初始化的。
如果我们刻意的将静态变量的声明和静态代码块的编写顺序打乱,系统依然是先执行静态变量的定义,而后执行静态代码块。
3、定义时初始化和静态代码块初始化的顺序
Test1.java
packagecom.test;
publicclassTest1{
static{
i=9;
}
staticinti=8;//系统会为该变量默认初始化为0
staticintj=9;//intj;j=0;j=9;
static{
j=10;//j=10;
}
publicstaticvoidmain(String[]args){
System.out.println("i="+i);//i=8;
System.out.println("j="+j);//j=10;
}
}
编译并运行:
初始化的顺序和程序的执行顺序相同,都是由上向下执行。
9、构造代码块
1、构造代码块的定义
就是在类的内部定义的,且在方法的外部。
“{}”前没有任何修饰符。
2、例子
Test2.java
packagecom.test;
publicclassTest2{
{
System.out.println("这是构造代码块。
");
}
}
编译并运行:
得到的结论是:
它和静态代码块不一样,不会被虚拟机自动调用。
3、构造代码块的功能
对非静态属性初始化。
Test2.java
packagecom.test;
publicclassTest2{
{
System.out.println("i="+i);
}
inti;//虚拟机会默认为其初始化为0。
publicstaticvoidmain(String[]args){
}
}
编译:
报“非法向前引用”错误。
将上面的程序修改:
Test2.java
packagecom.test;
publicclassTest2{
{
i=9;
//System.out.println("i="+i);//报错“非法向前引用”
}
inti;//虚拟机会默认为其初始化为0。
publicstaticvoidmain(String[]args){
}
}
编译并运行:
说明:
构造代码块就是为非静态属性初始化的。
将上面的程序进一步修改:
Test2.java
packagecom.test;
publicclassTest2{
{
i=9;
//System.out.println("i="+i);//报错“非法向前引用”
}
inti=8;//虚拟机会默认为其初始化为0。
intj=9;
{
j=10;
}
publicstaticvoidmain(String[]args){
//非静态属性如何访问:
System.out.println("i="+newTest2().i);
System.out.println("j="+newTest2().j);
}
}
编译并运行:
上面的三个程序说明:
属性的定义和构造代码块的执行顺序是:
先定义变量,后执行构造代码块。
但是初始化的顺序依然是由上向下执行。
10、如何访问非静态方法和非静态属性
我们不能够像访问静态方法和静态属性一样来访问非静态的方法和属性。
Test3.java
packagecom.test;
publicclassTest3{
inti=9;
voidprint(){
System.out.println("非静态方法。
");
}
publicstaticvoidmain(String[]args){
System.out.println(Test3.i);
Test3.print();
}
}
编译:
报错“无法从静态的上下文环境中访问非静态的属性或方法。
”
1、如何调用非静态的属性和方法
我们要想访问非静态的,必须要实例化对象,然后通过对象,或对象的引用来访问该类型的属性或方法。
2、如何实例化对象
如何实例化对象?
用“new”关键字加类名称加([……]),来实例化对象。
Test3.java
packagecom.test;
publicclassTest3{
inti=9;
voidprint(){
System.out.println("非静态方法。
");
}
publicstaticvoidmain(String[]args){
newTest3().