Java基础知识(四)类的三大特性
封装
将成员(属性or方法)设置为私有,只能通过其他成员方法调用被设置为私有的方法或属性,这就叫做类的封装。也就是直接在类外访问、调用不了(这就将成员封装起来了!)
用关键字private修饰的成员就成为了私有成员,被封装起来。
public class Test{
private String name;
public static void main(String[] args){
Test test = new Test();
test.print(); //这样调用
//System.out.println(test.name); 试试将这行代码解注释了看看会不会报错。
}
public Test(){ //还记得吗这个函数?
name = '小小';
}
public void print(){
System.out.println(this.name);
}
}
继承
继承就是将父类的成员、方法继承过来。比如说你的父亲老了,要将公司让给你管理,你就是继承了你父亲的公司,公司里的员工还是以前的员工、公司的运作还是照原样运作,这就是将员工(属性)、运作方法(方法)继承给你。(但是你还可以在此基础上增加你自己的员工、亲信或者运作方法)
Java的继承只有单继承。【c++程序猿要注意】。子类会继承父类的全部成员,但是只能访问public成员。
继承的写法
继承通过关键字extends操作。
//父亲类
class Father{
private String name;
public int money;
public String getName(){
return this.name;
}
}
//子类,继承了父类
class Son extends Father{
public int age;
}
public class Application(){
public static void main(Stringp[] args){
Son son = new Son();
System.out.println(son.age); //输出0
System.out.println(son.money); //儿子没money但是继承了父亲的了,就有了
//System.out.println(son.name); //试试这个可不可以输出?
}
}
super
在子类中可以通过super“ . ”调用父类的成员。
public class Father{
public String name;
public String getName(){
return this.name;
}
}
class Son extends Father{
int age;
public Son(){
//super();
//构造方法在方法体中的最顶端有一个super()方法的调用,在创建对象时初始化父类对象(隐藏起来了)
}
public Son(String name, int age){
//在这也有个super()
super.name = name;
this.age = age;
}
public printEverything(){
System.out.printf("%s, %d", super.getName(), this.age);
}
}
super注意点:
- super( )初始化父类,必须出现在子类构造方法的最顶端。
- super只能出现在子类方法或构造方法中。(不要想着实例化对象也能调用)
- super( ) 和 this( ) 不能同时出现在子类构造函数中。
扩展一下访问权限问题:权限开放由大到小,public,protected,default,private
- public:在任何地方都可以访问。
- protected:在一个包内的任何地方都可以访问,包外只有它所在的类的子类中才可访问。
- private:只有在它所在的类中可以访问。(实例化对象都不可以调用)
多态
在介绍多态之前先介绍一下方法的重写。
方法重写:方法名、参数列表与父类中的方法名、参数列表完全相同。(注意不要与方法的重载混淆,方法的重载是方法名相同、参数表不同)相当于c++的虚函数,但是不需要修饰符。
class Father{
public void print(){
System.out.println("我是父亲");
}
}
class Son extends Father{
public void print(){
System.out.println("我是儿子");
}
public void say(){
System.out.println(111);
}
}
public class Application(){
public static void main(String[] args){
Son son = new Son();
Father father = new Son(); //可以这样写的,父类引用指向子类对象
son.print(); //和你想得一样,当然是输出 我是儿子 了
father.print(); //这个输出的是 我是儿子,是不是与你想的不同。为什么?当然是因为子类中重写了
//实际上是进行了向上类型转换了(由子类对象转换成父类对象了)
//father.say() 这是不能错误的
/*能输出什么,看等号左边的类有什么。输出的是什么,看等号右边的类中是什么。*/
}
}
向上类型转换是自动的、默认的,而向下类型转换是需要强制的、手动的。这点与基础类型学习的类型转换一致。
然后介绍多态,多态实在方法重写的基础上进行的。实现动态编译,提高扩展性。多态的实现就是靠父类引用既可以指向父类对象、也可以指向子类对象。那么在输出的时候就可以输出两种东西了。(子类and父类,这就是为什么实在重写的基础上实现的)
class Father{
public void print(){
System.out.println("我是父亲");
}
}
class Son extends Father{
public void print(){
System.out.println("我是儿子");
}
}
public class Application(){
public static void main(String[] args){
Son son = new Son();
Father[] father = new Son[10]; //可以这样写的,父类引用指向子类对象
father[2] = son;
for(int i = 0;i < 10;i++){
father[i].print(); //在编译时不晓得,在运行时才知道类型
}
}
}
instanceof关键字
instanceof关键字用于判断一个对象是否是一个类或者其子类类型。
class Father{
}
class Son extends Father{
}
public class Application(){
public static void main(String[] args){
Son son = new Son();
Father father = new Father();
System.out.println(son instanceof Son); //true
System.out.println(son instanceof Father); //true
System.out.println(son instanceof String); //false
System.out.println(father instanceof Object); //true
}
}
抽象类
类的特征之一是抽象,抽象类比它还抽象。抽象类由规则(抽象方法,c++中的纯虚函数)与方法(虚函数)组成。抽象类中必有抽象方法,有抽象方法的必是抽象类。
抽象用abstract修饰符。
abstract class Test{
abstract void print();
public void say(){}
}
抽象类用于做基类,定义了一组规则,用子类将规则实现(方法的重写)。
接口
抽象类是一种规则、限制,接口比抽象类更限制化。在接口中只能定义抽象方法(在接口的定义中不写abstract也是可以的,它也定义为抽象)。相当于c++中的虚基类。
接口用interface修饰符。
interface Test{
void show();
abstract void print();
}
为接口写的实现类用implement关键字修饰
interface Test{
void show();
abstract void print();
}
class TestImpl implements Test{
void show(){
System.out.println(111);
}
void print(){
System.out.println(222);
}
}
一般为接口实现的类命名为接口名 + Impl