继承、多态、抽象类与接口
1、继承
在java中,继承语法与c++有所不同
class 子类 extends 父类{}
并且java只支持单继承,一个类只能有一个父类,子类在继承父类之后,创建子类对象的同时也会调用父类的构造方法。java虚拟机会先执行父类的构造方法,然后再执行子类的构造方法。
java虽然不允许同时继承两个父类,但不代表没有多继承关系,可以通过祖父-父亲-儿子的方式实现多继承。
2、Object类
在java中所有的类都直接或简介继承了java.lang.Object类,Object类是比较特殊的类,它是所有类的父类,是java类层中的最高层类。用户创建一个类时,除非已经指定要从其他类继承,否则它就是从java.lang.Object类继承而来的。java中的每个类都源于java.lang.Object类,如String类、Integer类等都是继承于Object类。除此之外,自定义的类也都继承于Object类。由于所有类都继承于Object类,所以可以省略extends。
在Object类中,主要包括clone(),finalize(),equals(),toString()等方法,由于所有类都是Object的子类,所以所有类都可以重写Object类中的方法。
但Object中的getClass(),notify(),notifyAll(),wait()等方法不能被重写,因为这些方法被定义为final类型
getClass()方法
可以返回对象执行时的class实例,然后使用此实例调用getName()方法可以取得类的名称,语法为getClass().getname();
toString()方法
将一个对象返回为字符串形式,它会返回一个String实例,在实际的应用中通常重写该方法,为对象提供一个特定的输出模式。当这个类转换为字符串或与字符串连接时,将自动调用重写的该方法。
看一个例子:学生自我介绍
public class test{
String name;
int age;
public test(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "我叫"+name+",今年"+age+"岁。";
}
public static void main(String [] args){
test s1 =new test("王小二",50);
System.out.println(s1);
}
}
输出:
3、equals()方法
在java语言中,有两种比较对象的方法,分别为“”==“”运算符和equals()方法,前者比较的是两个对象引用内存地址是否相等,后者比较的是两个对象的实际内容。
4、对象类型的转换
向上转型与向下转型,在向上转型时,父类的对象无法调用子类独有的属性或者方法。向下转型将一个较抽象的类转换为一个具体的类,是不安全的,需要进行强制转换
子类类型 子类对象=(子类类型)父类对象;
两个没有继承关系的对象不可以进行向上转型或者向下转型
父类对象可以强制转换为子类对象,但有一个前提,这个父类对象要先引用这个子类对象。
这个知识点在c++中类似于父类指针和子类指针的引用。
5、使用instanceof关键字判断对象类型
当再程序中执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生ClassCastException异常,所以在执行向下转型之前要养成良好的习惯,就是判断父类对象是否为子类对象的实例,可以使用instanceof关键字判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。
语法:某类的对象引用 instanceof 某个类 判断前者是否为后者的实例对象
使用instanceof关键字的表达式返回值为布尔值。
6、方法重载
与c++重载类似。
7、final关键字
(1)声明一个常量,必须在声明时进行赋值。
(2)定义final方法,防止子类修改父类的定义与实现方式,使子类无法重写父类,同时定义为final的方法执行效率要高于非final方法,一个定义为private的方法隐式的被指定为final类型,因此无须将一个定义为private的方法再定义成final类型。
(3)final类,不能被继承,该类中所有方法都被隐式设置为final方法,但是final类中的成员变量可以被定义为非final形式。
8、多态
与c++类似。多做练习。
9、抽象类与接口
抽象类:
public abstract class Parent{
abstract void testAbstract();
}//定义抽象方法
接口:
public interface Paintable {
void draw()
}//定义接口方法可以省略public abstract关键字
一个类继承一个父类的同时再实现一个接口
public class zilei extends fulei implements Paintable{
}
包和内部类
完整的类路径
当在程序中需要使用两个不同Date类的完整类路径时,如下
java.until.Date date=new java.until.Date();
java.sql.Date date2=new java.sql.Date(100);
同一个包中的类相互访问时,可以不指定包名。
导入包
import com.mr.*;//导入该包中所有类
import com.mr.Math;//导入包中的Math类
导入静态成员
import static 静态成员
内部类:
在一个类中使用内部类,可以在内部类中直接存取其所在类的私有成员变量。
class OuterClass{ //外部类
class InnerClass{ //内部类
}
}
在成员内部类可以随意使用外部类的成员方法以及成员变量,就算被修饰为private也可以使用。内部类的实例一定要绑定在外部类的实例上,如果从外部类中初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上。
(1)、使用this关键字获取内部类与外部类的引用
如果在外部类中定义的成员变量与内部类的成员变量名称相同,可以使用this关键字。
语法:在内部类中this.x调用内部类的x,外部类.this.x调用外部类的x
(2)、匿名内部类
匿名类是只在创建对象时才会编写类体的一种写法,特点是现写现用
语法:
类名 对象名=new 类名(){类体 };