Java学习 Part.1
1 类和对象
(1) 类相当于结构体,其中包括属性和方法。
*方法名区分大小写
(2) A a=new A();相当于A a=(A *)malloc(sizeof(A));
a为对象名,在栈中分配,相当于一个指针变量,存放着类对象的地址,A()为类对象,在堆中分配,相当于指向结构体的指针常量。
(3) 访问数据需通过 类对象名.成员 的方式来访问,类不可直接访问。
***类中的成员不能凭空出现,必须是以 类名(static)/类对象名.成员 的方式访问。
***字符串变量和常量都属于对象,基本数据类型的变量常量都不属于对象。
**若要使基本类型的变量调用方法,必须要把它封装成对象。例:
int i=10;
Integer in=new Integer();
in.toString();//in可以当作对象
j=in+1;//in也可以当作常量
(4) 类中可以创建一个类本身的对象作为属性。
(5) 类之间的关系:一般到特殊(学生和男学生)、包含与被包含(汽车和轮子)、使用和被使用(货车和司机)。
(6) 定义类时,每个单词首字母大写。定义方法时,第一个单词首字母小写,其他每个单词首字母大写。
*(7) 如果不是内部类只能加public、default、final,不能加private、protected。
*(8) 一个程序只能有一个public类,且该类名为程序名。
//多个对象中有多个属性,但多个对象共用一个方法。
2 数据类型
*(1) float,Double都用%f输出。boolean用%b来输出。
(2) 常数默认为int类型,过长须在常数后加L。
(3) 实数默认为double类型,希望为float的话,应在实数后加F。将double类型的数赋给float会出错。
float x=2.2;//error
float x=2.2f;//OK
(4) if只能判断逻辑表达式。
if(3)//error
if(3>2)//ok
*(5) 优先级由低到高
byte/char/int/long/float/double 大容量转小容量时需强转(在前面加(数据类型))。
*(6) 字符串和任何非字符串相加,非字符串都回和字符串连接在一起。字符型与数字相加,会转化为数字相加。
(7) 除法的运算结果与运算对象的数据类型有关,若两个都为int,则商为int;若两个数中一个或两个为float,则商为float。
(8) 取余允许运算对象为实数,但结果的正负只与被除数相同。
(9) 变量在哪个函数内定义,才可以在哪个函数内使用。
*(10) 进制:printf("%d:十进制 %x:八进制 %X:大写八进制 %#x:十六进制 %#X:大写十六进制")
二进制:以OB开头; 八进制:以0开头; 十六进制:以0x开头;
(11) 运算符
位运算符:&(位与)、|(位或)、^(异或)、~(反码)、<<(左移)、>>(右移)、>>>(无符号右移)
逻辑运算符:&&(短路与)、||(短路或)、!(逻辑非)、&(逻辑与)、|(逻辑或)
//& | 既可作位运算符,也可作逻辑运算符。
&& 与 & 区别:对于&&,如果 a 为 false,则不计算 b(因为不论 b 为何值,结果都为 false)。
|| 与 | 区别:对于||,如果 a 为 true,则不计算 b(因为不论 b 为何值,结果都为 true)。
3 访问控制符
(1) private protected public
(2) 针对类外部,内部之间可以彼此访问。
(3) 只有private不能在外部访问。
4 构造方法
(1) 没有返回值,构造方法名与类名相同。
(2) 创建对象时,对象直接执行构造方法,创建时可发送实参给构造函数形参,实现初始化。
(3) 若没有构造方法且新建类对象时未传递参数,系统会自动生成一个无参的构造函数;若编程者为类定义了构造方法,则系统不会生成默认的构造函数。
(4) 一个对象被创建时,会对各个属性进行初始化赋值。数值型默认为0,逻辑型默认为false,引用类型默认为NULL。
(但局部变量,即在函数内部的变量,必须赋值后方能被使用。)
系统会先执行定义时所赋的初值,然后再执行构造函数中赋的初值。
*(5) 构造方法可以有多个,但根据形参类型、数量、顺序只会有一个构造方法被调用。
*(6) 构造方法为private,则不能创建类对象。
*(7) 任何类里一定有一个构造方法。如果没有添加,系统会自动创建。
生成对象一定会调用类里面的构造方法,而且只调用一个。
5 函数的重载
//同名不同参
//返回值不同不能构成重载的依据。
(1) 同名的函数通过不同的形参做相同或相似的事情。
(2) 函数的形参个数、顺序、数据类型至少有一个不一样。
(3) 如果两个函数只是返回值不一样,不能构成重载。
6 this指针
(1) 是一个系统隐含的指针,被自动附加在非静态的成员函数参数列表中。
当前时刻,哪个对象调用该函数,那么this就指向当前调用该函数的对象。
系统会自动在该函数的参数列表中添加一个隐藏的this指针,并且把调用该函数的对象的地址赋给this指针。
这样一来,在函数的内部通过this就可访问当前正在调用该函数的对象的成员。
**(2) 关键字his代表当前正在调用该方法的那个对象,具体可分为两种情况:
在普通方法中,关键字his代表方法的调用者、即本次调用了该方法的对象;
在构造方法中,关键字this代表了该方法本次运行所创建的那个新对象。
***(3) 同类的不同对象中,为属性多次分配内存,而为方法则只分配一次内存,各对象通过this指针调用同一个方法。
public void show(A *this){
System.Out.printf("i=%d/n",*(this).i);
}
当前时刻哪一对象调用方法,那么this就指向调用方法的对象。
(4) 静态方法内没有this指针。因为静态方法属于类本身,this代表区分使用的类对象。
(5) this多用于区分同名的形参和变量
Class Student{
private String name;
private int age;
public student(String name,int age){
this.name=name;
this.age=age;
}
public void ShowInformation(){
System.Out.printf("name=%s,age=%d",name,age);
}
}
7 static
*(1) 多个类对象共用一个static属性或方法。
*(2) static属性或方法属于类本身。或者说:我们可以通过访问类名的方式直接访问类内部static属性或方法。
(3) static属性或方法也属于类对象。我们也可以通过类对象名的方式访问。
(4) 严格来讲,static属性或方法仍属于类本身。
(5) static只是表明了改成员具有了可以通过类名访问的访问的潜在特征。但是是否可以通过类名访问,还必须满足一个条件:该成员不是private。
**(6) 静态方法只能访问静态成员,不能访问非静态成员,非静态方法可以访问静态成员和非静态成员。(针对类内部)
因为静态方法在类加载后就已经存在了,而非静态方法是在创建一个类对象时才分配内存空间,而要想调用一个方法,这个方法必须些存在。
所以静态方法存在时,非静态成员未必存在;非静态方法存在时,静态方法必定存在。
*(7) static只能修饰普通方法,不能修饰构造函数。
***(8) static不修饰局部变量,即方法内的变量。
8 类的继承
(1) 一个新类从已有的类那里获得其已有的属性和方法。新类被称为子类,已有的类被称为父类。
(2) class 子类 extends 父类{
......
}
*(3) 子类内部访问:子类的所有方法内部都可以访问父类除私有成员以外的所有成员。所谓子类的所有的方法包括子类的私有方法。
子类对象外部访问:父类除私有成员外的所有成员。
总结:子类可以继承父类除私有成员外的所有成员。
(4) 私有物理上已被继承过来,只不过逻辑上程序员无法访问它。因此,继承须慎重,否则会浪费内存。
*继承过来的私有属性,不可以直接访问,但是可以通过某些方法间接调用,即用super.方法名() 调用父类中其他函数。
*(5) 只有子类与父类是一般到特殊的关系时,才能使用继承。例如:学生和男学生,男学生和男小学生。
(6) java只支持单继承,即一个类只能有一个父类,不支持多继承,但可以有多层继承,,即一个类可以继承另一个类的子类。
*(7) 子类能继承父类的构造方法。但在子类的构造方法中必须使用语句super(参数列表)调用父类的构造方法。
(8) 子类访问父类成员的三种方式:在子类内部访问父类成员、通过子类对象名访问父类成员、通过子类的类名访问父类成员。
(9) 子类继承父类,该子类作为父类被子类继承,如此往复形成的树,叫族群。
(10) 子类内部不可以生成父类对象。
9 Super
class a extends b{
public a(子类和父类构造函数形参){
super(父类构造函数形参);//调用父类构造函数
}
}
(1) 每一个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造方法,那么在编译时会报错。
(2) 如果显示地写出了super()语句,则必须保证该语句是子类构造方法中的第一条语句,不能写在普通方法中(调用构造方法表明对象正在被构造,调用普通方法说明对象已被构造完成),否则也会报错。
*(3) super()语句如果不写,则编译器会自动添加,所以此时如果父类没有无参的构造方法,则会报错。
*(4) 既可以显示写super(),前提是父类必须有无参的构造方法。也可以显示写super(参数),前提是父类必须有带参的构造方法。
(5) 调用父类的构造方法的语句必须借助于super(),不能直接写父类的类名。
(6) 一个构造方法中super() 语句不能写两条。
*(7) super.方法名()调用父类中其他函数。当子类方法重写父类方法时,super.方法名()仍可调用父类未被重写的方法。
10 重写
*(1) 在继承的前提下。
(2) 在子类中重新定义父类中已有的方法。
*(3) 重写方法必须和被重写方法具有相同的方法名称、参数列表和返回值类型。
//与重载区别:不止同名同返回值,也要同参。
*(4) 重写方法时,不能使用比父类中被重写方法更严格的访问权限。(例:若父类方法为public,则子类重写方法不能为protected、default、private)
//父类方法权限范围要大于子类重写方法权限范围,否则不能实现多态。
(5) 严格来讲,重写并非方法的重新更改和覆盖,子类从父类中继承了一个方法,并重新定义了一个方法,两个方法同名同参同返回值。
通过类对象调用时,会优先选择重写后的。
***(6) @Override 写在重写函数之前,若重写方法时方法签名写错,编译时会报错。
11 多态
(1) 一个父类的引用类型变量,它既可以指向父类对象也可以指向子类对象,它可以根据当前时刻指向的不同,自动调用不通对象的方法,这就是多态。
通过指向子类的父类引用,调用子类中从父类继承的、重写的成员。
*(2) 子类对象可以直接赋给父类引用 ,但父类对象在任何情况下都不可以直接赋给子类对象。
*父类的两个同级子类引用也不可以相互赋值。
若直接把父类引用强制转化为子类引用,赋给子类引用,编译不会出错,但运行会出错。
**只有在父类引用本身指向的就是一个子类对象时,才可以把父类引用强制转化为子类引用 。
例:A为父类,B为子类,且当前时刻A类对象a指向B类对象,可 B b=(B)a; 此时可以用b来调用B类中所特有的方法。
//为了将父类引用转化为子类引用,并用其来调用子类特有成员。
比喻:因为子类是父类的一种,但父类不是子类的一种。动物是父类,狗是子类。狗可以说是动物,动物不可以说是狗。
(3) 优点:同样一行代码做不同的事情。
***(4) 多态只能通过父类引用访问子类对象从父类中继承过来的、 重写的成员 ,不能通过父类引用访问子类对象所特有的成员。
理解成:父类引用仍是父类类型,即使指向子类类型,但还是只能操作父类类型的数据和方法。
//只能访问子类从父类继承过来的成员。
12 抽象类
(1) 抽象类通常用来作为一个类族的最顶端的父亲,用最底层的类表示现实中的具体事物,用最顶层的类表示该族所有事物的共性。
*(2) 在定义java方法时可以只给出方法头,而不给出方法内部实现代码,这样的方法称为抽象方法。(有关键字abstract、句尾有;、没有方法体)
*(3) 凡是没有方法体的方法必须要使用关键字abstract修饰为抽象方法。
*(4) 凡是含有抽象方法的类都必须要声明为抽象类。
(5) 用abstract关键字来修饰一个类时,该类叫做抽象类。
(6) 包含抽象方法的类一定是抽象类,抽象类不一定包含抽象方法。
*(7) 父类为非抽象类,子类可以为抽象类。
*(8) 父类若为抽象类,则子类若继承父类的抽象方法,也成为抽象类。若要成为非抽象类,必须实现父类中的抽象方法,即重写父类中的抽象方法。
总结:要么加abstract,要么重写方法。
*(9) 抽象类不能定义一个抽象类的对象,但能够定义一个抽象类的引用(相当于指针),可以利用该引用指向真正实现它的子类对象,实现多态。
//抽象类可以定义引用,实现多态。
13 Final
(1) 可修饰整个类和类中的若干个成员(若干个属性和方法)。
*(2) final修饰类表示该类***不能被继承***。
*(3) final修饰类中的若干属性表示该属性必须被赋值并且***只能被赋一次值***(默认值不能算真正的的赋值)。
初始化方式有两种(只能选择其中的一种):在定义成员变量的同时初始化、在类中所有的构造函数中初始化。
注意:一个类的所有普通方法内部的都不可修改final修饰过的成员变量的值。因为final修饰的属性只能被赋值一次。
*(4) final修饰类中的若干方法表示该方法可以被子类继承,***不可以被子类重写***。
14 接口
(1) 接口是抽象方法和常量值的结合。从本质上讲,接口是一种特殊的抽象类。
(2) interface 接口名 extends 接口1,接口2{
常量定义和抽象方法定义
}
一个接口可以继承多个接口
***(3) 接口中定义的属性必须是public static final的,而接口中定义的方法则必须是public abstract的,因此这些修饰符可以部分或全部忽略。
*(4) 接口中定义的属性的值在实现类中不能被更改。
(5) 一个类只能实现implements某个接口,不能继承extends某个接口,但接口可以继承接口,而且可以继承多个接口,即接口允许多继承。
*(6) 如果一个类只实现了一个接口的部分方法,则该类必须声明为抽象类。
(7) 一个类可以在继承一个父类接口的同时实现(implements)一个或多个接口,但***extends关键字必须在implements之前。
*(8) 不可以new接口对象,但可以定义一个接口引用类型的变量并将其指向实现接口的对象,达到多态的目的。
//接口可以定义引用,实现多态。
(9) 一个类要想实现某接口中的方法时,必须得在方法返回值前加public。
重写时要加public
(10) 接口与抽象类的区别
接口中的方法不允许有方法体,但抽象类却允许。
java类不允许多继承,接口确允许多继承。
15 编译运行含有包层的类
(1) package语句必须得是第一条语句。
(2) package zhangsan.lisi表示:
把该文件中所有的类放入zhangsan.lisi这个包中,并且该文件中所有的类真正的名字将是包名和类名的组合。
如:类TestPackage的名字将变成zhangsan.lisi.TestPackage,而不再是TestPackage。
(3) 编译时建议使用javac -d . TestPackage.java尽量不要使用javac TestPackage.java,因为后者要自己手动建立包目录。
编译:javac -d . 文件名 运行:java 包名.类名
(4) 如果不在当前路径下运行程序,则必须保证class文件的最上层目录大的父目录位于classpath下。
(5) java zhangsan.lisi.TestPackage解析
先检查当前目录下是否有zhangsan/lisi这个包(包即文件夹),如果有,再检查该包下是否有zhangsan.lisi.TestPackage这个类。
如果都没有,编译器将再去classpath设置的路径中依次查找。如果都查找失败,则运行时出错。
16 同包和不同包类的相互访问
(1) 在同一个包中的类彼此可以相互访问,只要是非私有成员都可以被同包的另一个类访问,也只有私有的不能被继承。
(2) 在不同包没有任何关系的两个类,只有public类的public成员才可以被另一个包中的类访问。
default、private、protected的类不可被访问,public类中的default、private、protected的方法和属性也不可被访问。
编译时,要编译两个java文件,先编译被使用的,后编译使用的。
(3) 在不同包中有继承关系的两个类,只有public类的public成员和public类protected成员可以被另一个包中的子类在内部使用。
但是在子类的外部,通过子类对象名只能访问父类中的public成员。
(4) 使用不同包中类三种方式:
使用一个类的全名(包名.类名)、使用import语句导入一个包中所有的类(import 包名.*;)、使用import语句的导入一个包中特定的类(import 包名.类名;)。
(5) 在不同包中有继承关系的两个类,只有public类的public成员和public类的protected成员可以被另一个包中的子类在内部使用。
但是在子类外部(即通过子类对象名访问)只能访问父类中的public成员。
***总结
(1) 同包同类访问
类内部访问:public、protected、default private成员
(2) 同包不同类访问
通过对象访问:public、default类的public、protected、default成员
(3) 同包不同类继承访问
类内部访问:public、default类的public、protected、default成员,有时可间接访问private成员
通过对象访问:public、default类的public、protected、default成员,有时可间接访问private成员
(4) 不同包不同类访问(前提:import)
通过对象访问:public类的public成员
(5) 不同包不同类继承访问(前提:import)
类内部访问:public类的public、protected成员
通过对象访问:public类的public成员
17 jar包
(1) 将所要生成的jar包放入一个空文件夹。
(2) 进入cmd,进入该文件夹。
(3) 键入jar -cvf/-tf/-xf jar包名.jar *
cvf以详细的信息把创建jar包的过程输出。
tf在dos下显示jar包解压后的文件内容
xf把文件中的内容解压到当前目录下
*表示把当前目录所有文件打成jar包
(4)如何使用jar包中的类:假设现在有一个t.jar包,要想在任何目录下都可以访问t.jar包中的类。
则设置classpath时,必须把包名t.jar也设置进去,因为t.jar也相当于一个目录。
(5) 可运行jar包生成步骤
<1> 新建一个记事本文件,假设为1.txt,文件内容:
Main-Class: 可运行类的名字(:后有一个空格)
附注:记着敲回车
<2> dos下命令:
jar cvfm test.jar 1.txt *.class
记住:只有GUI程序生成的class文件才可以作为main

浙公网安备 33010602011771号