一、Java对象和类
Java作为一种面向对象语言,支持一下基本概念:
类
对象
实例
方法
属性
消息解析
封装
继承
多态
抽象
对象和类的概念:
对象:对象是类的一个实例,有状态和行为。如:一条狗是一个对象,它的状态有:颜色、名字、品种;行为有摇尾巴、叫、吃等。
类:类是一个模板,它描述一类对象的行为和状态。
一个类包含的变量类型:
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量在类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为static类型
局部变量:在方法、构造方法或者语句块中定义的变量成为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
public class Dog{ //Dog为类的对象
String name; //name成员变量
static String age; //age类变量也称静态变量
Dog(){ //对象
}
}
构造方法
每个类都有构造方法。如果没有显式的为类定义构造方法,Java编译器将会为该类提供一个默认的构造方法。
在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。
创建对象
对象是根据类创建的。在Java中,使用关键字new来创建一个新的对象。创建对象需要以下三步:
声明:声明一个对象,包括对象名称和对象类型。
实例化:使用关键字new来创建一个对象。
初始化:使用new创建对象时,会调用构造方法初始化对象。
public class Dog{
public Dog(String name){
System.out.println("Dog name is :"+name);
}
public static void main(String[]args){
Dog dog =new Dog("小花")
}
}
输出结果: Dog name is:小花
二、访问修饰符
Java通过修饰符来控制类、属性和方法的访问权限和其他功能,通常放在语句的最前端。
Java修饰符分为访问修饰符和非访问修饰符。
访问修饰符有以下四种:
public :共有得,对所有类可见
protected:受保护的,对同一包内的类和所有子类可见。
private:私有的,在同一类内可见。
默认的:在同一包内可见,默认不使用任何修饰符。
private yes no no no
缺省 yes no yes no
protected yes yes yes no
访问控制和继承
父类中声明为public的方法在子类中也必须为public。
父类中为protected的方法在子类中要么声明为protected,要么声明为public。不能声明为private。
父类中默认修饰符声明的方法,能够在子类中声明为private.
父类中声明为private的方法,不能够被继承。
总之:在子类声明的方法必须比在父类声明的方法作用范围广。
三、Java方法中的继承与重载
继承可以理解为一个类与另一个类获取方法和属性的过程。如果类B继承类A,那么B就拥有A的方法和属性。继承使用extends关键字。
Java中方法重载
在Java中,同一个类中的多个方法可以有相同的名字,只要他们的参数列表不同就可以,这被称为方法重载。
即方法名相同,参数列表不同(参数的类型,参数的个数,参数的顺序)
如:
public class Demo{
void test(){
System.out.println("a:"+a);
}
void test(int a){
System.out.println("a:"+a);
}
void test(int a,int b){
System.out.println("a+b:"+a" "+b);
}
void test (int b,int a){
System.out.println("a+b:"+a+" "+b);
}
double test(double a ){
return a;
}
}
说明:
参数列表不同包括:个数不同、类型不同和顺序不同。
仅仅参数变量的名称不同是不可以的。
跟成员方法一样,构造方法也可以重载。
声明为final的方法不能被重载。
声明为static的方法不能被重载,但是能够被再次声明。
方法的重载的规则:
方法名称必须相同。
参数列表必须不同。
方法的返回类型可以相同也可以不同。
仅仅返回类型不同不足以成为方法的重载。
方法重载的实现:
方法名称相同时,编译器会根据调用的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错,这叫做重编分辨。
Java继承中方法的覆盖和重载
如果在子类中定义一个方法,其名称、返回值类型和参数列表正好与父类中的相同,那么子类方法覆盖父类方法。
被覆盖的方法在子类中只能通过super调用。
注: 覆盖不会删除父类中的方法,而是对子类的实例隐藏,暂时不使用。
方法覆盖的原则:
覆盖方法的返回类型、方法名称、参数列表必须与原方法的相同。
覆盖方法不能比原方法的访问性差(即访问权限不允许缩小)。
覆盖方法不能比原方法抛出更多的异常。
被覆盖的方法不能是final类型。
被覆盖的方法不能为private,否则在其子类中只是定义了一个新的方法,并没有对其进行覆盖。
被覆盖的方法不能是static。如果父类中的方法是静态的,而子类中的方法不是静态的,但是两个方法除了这么一点外其他都满足覆盖条件,那么会发生编译错误;反之亦然。即使父类和子类的方法都是静态的,并且满足条件,但是仍然不会发生覆盖,因为静态方法是在编译的时候把静态方法和类的引用类型进行匹配。
覆盖和重载的不同:
方法覆盖要求参数列表必须一致,而方法重载要求参数列表必须不一致。
方法覆盖要求返回类型必须一致,方法重载对此没有要求。
方法覆盖只能用于子类覆盖父类的方法,方法虫子啊用于同一类中的所有方法(包括从父类中继承而来的方法)
方法覆盖对方法的访问权限和抛出的异常有特殊的要求(如父类方法为private,子类不能对其访问),而方法重载在这方面没有任何限制。
父类的一个方法只能被子类覆盖一次,而一个方法可以在所有的类中可以重载多次。
四、Java多态
public class demo{
public static void main(String [] args){
People obj=new People();//引用父类实例
obj.say();
obj=new Teacher();//引用子类实例
obj.say();
}
}
class People {
String name="良民"
void say(){
System.out.println("大家好,我是良民");
}
}
class Teacher extends People{
String name=“老师”;
void say(){
System.out.println("大家好,我是一名老师");
}
}
运行结果:
大家好,我是良民
大家好,我是一名老师
可以看出,obj既可以是人类,也可以是老师,它有不同德表现形式,这就被称为多态。多态是指一个事物有不同的表现形式或形态。
多态存在的三个必要条件:要有继承、要有重写、父类变量引用子类对象。
当使用多态方式调用方法时:
首先检查父类中是否有该方法,如果没有,则编译错误;如果有,则检查子类是否覆盖了该方法。
如果子类覆盖了该方法,就调用子类的方法,否则调用父类的方法。
如果父类和子类存在相同的变量a,那么obj.a调用的是父类的变量。要调用子类中的变量,则须向下转型。
Java多态对象的类型转换
在继承链中,我们将子类向父类转型成为“向上转型”,将父类向子类转型称为“向下转型”。
注意:不能直接将父类的对象强制转换为子类类型,只能将向上转型后的子类对象再次转换为子类类型。也就是说,子类对象必须向上转型后,才能再向下转型。
People obj =new Teacher();//向上转型
obj.say(); //调用的是子类方法
System.out.println(obj.name);//调用的是父类变量name
Teacher obj1=(Teacher)obj;//向下转型
System.out.println(obj1.name); //调用的是子类的变量name
总结:对象的类型转换再程序运行时检查,向上转型会自动进行,向下转型的对象必须是当前引用类型的子类。
五、Java关键字
Java this关键字
this关键子用来表示当前对象本身,或当前类的一个实例,通过this可以调用本对象的所有方法和属性。
注意:this只有在类实例化后才有意义。使用this区分同名变量
public class Demo{
String name;
int age;
Demo(String name,int age){
this.name=name;
this.age=age
}
}
this也可以用来作为方法名来初始化对象,也就是相当于调用本类的其他构造方法,它必须作为构造方法的第一句。如:
public class Demo{
String name;
int age;
public Demo(){
this("新华苑“,3)
}
public Demo(String name,int age){
this.name=name;
this.age=age;
}
}
Java super关键字
super关键字与this关键字类似,this用来表示当前的实例,super用来表示父类。
super可以用在子类中,通过点号(.)来获取父类的成员变量和方法。
super关键字的功能:
调用父类中声明为private的变量。
点取已经覆盖了的方法。
作为方法名表示父类构造方法。
调用隐藏变量和被覆盖的方法
注意:
无论是super()还是this(),都必须放在构造方法的第一行。
在构造方法中调用另一构造方法,调用动作必须置于最初始的位置。
不能在构造方法以外的任何方法内调用构造方法。
在一个构造方法内只能调用一个构造方法。
如果编写一个构造方法,既没有调用super()也没有调用this(),编译器会自动插入一个调用到父类构造方法中,而且不带参数。
super与this的区别:super不是一个对象的引用,不能将super赋值给另一个对象变量,它只是一个指示编译器调用父类方法的特殊关键字。
Java static关键字
static能够与变量、方法一起使用,表示是”静态“的。
静态变量和静态方法能够通过类名来访问,不需要创建一个类的对象来访问该类的静态成员,所以static修饰的成员又称作类变量和类方法。
静态变量属于类,不属于任何独立的对象,所以无需创建类的实例就可以访问静态变量。
注意:static的变量是在类装载的时候就会被初始化。也就是说,只要类被装载,不管你是否使用了这个static变量,它都会初始化。
小结:类变量用关键字static修饰,在类加载的时候,分配类变量的内存,以后再生成类的实例对象时,将共享这块内存(类变量),任何一个对象对类变量的修改,都会影响其他对象。外部有两种访问方式:
静态方法:静态方法是一种不能像对象实施操作的方法。
关于静态方法的总结:
一个类的静态方法只能访问静态变量;
一个类的静态方法不能够直接调用非静态方法;
静态方法中不存在对象,因而不能使用this,当然也不能使用super;
静态方法不能被非静态方法覆盖;
构造方法不允许声明为static的;
注意:实例变量只能通过对象来访问,不能通过类访问。
Java final关键字
在Java中,声明类、变量和方法时,可使用关键字final来修饰。final所修饰的数据具有”终态“的特征,表示”最终的“意思。具体规定如下:
final修饰的类不能被继承。
final修饰的方法不能被子类重写。
final修饰的变量(成员变量或局部变量)即成为变量,只能赋值一次。
final修饰的成员变量必须在声明的同时赋值,如果在声明的时候没有赋值,那么只有一次赋值机会,而且只能在构造方法中显示赋值,然后才能使用。
final修饰的局部变量可以只声明不赋值,然后再进行一次性的赋值。
final一般用于修饰那些通用性的功能、实现方式或取值不能随意被改变的数据,以免被误用。
需要注意的是,如果将引用类型(任何类的类型)的变量标记为final,那么该变量不能指向任何其他对象。但可以改变对象的内容,因为引用本身是final的。
final可以用来修饰类(放在class关键字前面),阻止该类再派生出子类。
final也可以用来修饰方法,被final修饰的方法不能被覆盖;变量也可以被final修饰,被final修饰的变量在创建对象以后就不允许改变他们的值。一旦将一个类声明为final,那么该类包含的方法也将被隐式的声明为final,但是变量不是。
被final修饰的方法为静态绑定,不会产生多态(动态绑定),程序在运行时不需要再检索方法表,能够提高代码的执行效率。
六、Java包装类、拆箱和装箱
每个包装类的对象可以封装一个相应的基本类型的数据,并提供了其他一些有用的方法。包装类对象一经创建,其内容(所封装的基本类型数据值)不可改变。
由基本类型向对应的包装类转换成为装箱,如把int包装成Integer类的对象;
由包装类象对应的基本类型转换成为拆箱,如把Integer类的对象重新简化为int。
public class Demo{
public static void main(String[]args){
int m=500;
Integer obj=new Integer (m);//手动装箱
int n=obj.intValue();//手动拆箱
System.out.println("n= "+n);
Integer obj1=new Integer(500);
System.out.println("obj等价于obj1?"+obj.equals(obj1));
}
}
运行结果:
n=500
obj等价于obj1?true
将字符串转换为整数
Integer类有一个paseInt()方法,可以将字符创转换为整数,语法为:
parseInt(String s,int radix);
s为要转换的字符串,radix为进制,可选,默认为十进制。
public class demo1 {
public static void main(String[] args) {
String str[] = {"123", "123abc", "abc123", "abcxyz"};
for(String str1 : str){
try{
int m = Integer.parseInt(str1, 10);
System.out.println(str1 + " 可以转换为整数 " + m);
}catch(Exception e){
System.out.println(str1 + " 无法转换为整数");
}
}
}
}
运行结果: 123可以转换为整数123
123abc 无法转换为整数
abc123 无法转换为整数
abcxyz 无法转换为整数
将整数转换为字符串
Integer类有一个静态的toString()方法,可以讲整数转换为字符串。如:
public class Demo{
public static void main(String []args){
int m=500;
String s=Integer.toString (m);
System.out.println("s= "+s);
}
}
运行结果
500
自动拆箱和装箱
public class Demo{
public static void main(String []args){
int m=500;
Integer obj=m;//自动装箱
int n=obj; //自动拆箱
}
}