6、面向对象特性

一、继承

继承用来解决成员变量或方法大量重复的问题, 将重复代码抽取到父类中 

使用方法
//父类A
public class A{
    int a;                 //缺省(包权限),仅能在本包中使用
    private int b;        //私有,仅能在本类中使用
    public int c;        //公有,在任何地方都可使用
    protected int d;    //保护类,缺省+不同包子类
    
    public String toString(){...}
}

//假设有类B继承类A
public class B extends A{
    int a;         //变量的隐藏
    public String toString(){...}    //方法的重载(重写)
}
 
1
//父类A
2
public class A{
3
    int a;                 //缺省(包权限),仅能在本包中使用
4
    private int b;        //私有,仅能在本类中使用
5
    public int c;        //公有,在任何地方都可使用
6
    protected int d;    //保护类,缺省+不同包子类
7
    
8
    public String toString(){...}
9
}
10
 
          
11
//假设有类B继承类A
12
public class B extends A{
13
    int a;         //变量的隐藏
14
    public String toString(){...}    //方法的重载(重写)
15
}

//编译器会一直上溯到最顶端的超类,执行该类构造方法,然后依次执行各子类构造函数

class A{							
	public A(){
		System.out.println("调用了A类的构造方法");
	}		
}
class B extends A{					
	public B(){
		System.out.println("调用了B类的构造方法");
	}	
}
public class C extends B {
	public C(){
		System.out.println("调用了C类的构造方法");
	}
    
	public static void main(String args[]) {
		C c=new C();
	}
}

/*
程序运行结果:
调用了A类的构造方法
调用了B类的构造方法
调用了C类的构造方法
/*
x
 
1
//编译器会一直上溯到最顶端的超类,执行该类构造方法,然后依次执行各子类构造函数
2
 
          
3
class A{                            
4
    public A(){
5
        System.out.println("调用了A类的构造方法");
6
    }       
7
}
8
class B extends A{                  
9
    public B(){
10
        System.out.println("调用了B类的构造方法");
11
    }   
12
}
13
public class C extends B {
14
    public C(){
15
        System.out.println("调用了C类的构造方法");
16
    }
17
    
18
    public static void main(String args[]) {
19
        C c=new C();
20
    }
21
}
22
 
          
23
/*
24
程序运行结果:
25
调用了A类的构造方法
26
调用了B类的构造方法
27
调用了C类的构造方法
28
/*
super关键字(重点)
表示对子类对父类的鹰用
如果在子类中未显式调用父类构造方法,则编译器会默认 使用super()自动调用父类的无参构造方法(默认/覆盖),假若父类没有提供无参构造方法,编译时将出错
//引用父类的成员(需要相应的访问权限):
    super.变量 
    super.方法([参数表])
    
//在子类构造方法中调用父类的构造方法:
    super([参数表]); //必须放在构造方法的第一行位置上
6
 
1
//引用父类的成员(需要相应的访问权限):
2
    super.变量 
3
    super.方法([参数表])
4
    
5
//在子类构造方法中调用父类的构造方法:
6
    super([参数表]); //必须放在构造方法的第一行位置上
instanceof运算符
用于判断一个类是否实现接口或判断一个对象是否属于一个类
//instanceof运算符格式
    对象 instanceof  类或接口
//结果:true或false
x
 
1
//instanceof运算符格式
2
    对象 instanceof  类或接口
3
//结果:true或false

使用注意事项
  1. 子类并不能继承父类的所有变量或方法,需要看父类成员的访问权限

二、多态

同一个引用类型,使用不同的示例而执行不同的结果
对象的类型转换
//子类转父类:向上转型
    子类对象句柄  =  (子类名) 父类对象;//需要强制转换,损失精度
    
//父类转子类:向下转型
    父类对象句柄  =  子类对象;
5
5
 
1
//子类转父类:向上转型
2
    子类对象句柄  =  (子类名) 父类对象;//需要强制转换,损失精度
3
    
4
//父类转子类:向下转型
5
    父类对象句柄  =  子类对象;
1、静态多态(编译时多态)
静态多态主要是指 方法重载, 与是否发生与继承没有必然联系
2、动态多态(运行时多态)
条件
  1. 必须要有继承的情况存在
  2. 在子类中重写父类的方法
  3. 必须由父类的引用指向派生类的实例,并且通过父类的引用调用重写的方法。(向上转型)
使用举例
//多态性的例子(续)
public class AnimalTest {
	public static void main(String args[]){
		Animal am=new Animal();
		am.roar();
		am=new Dog();
		am.roar();
		am=new Cat();
		am.roar();
	}
}
/*程序运行结果:
动物:...
狗:汪,汪,汪,...
猫:喵,喵,喵,...*/
12
 
1
//多态性的例子(续)
2
public class AnimalTest {
3
    public static void main(String args[]){
4
        Animal am=new Animal();
5
        am.roar();
6
        am=new Dog();
7
        am.roar();
8
        am=new Cat();
9
        am.roar();
10
    }
11
}
12
/*程序运行结果:
13
动物:...
14
狗:汪,汪,汪,...
15
猫:喵,喵,喵,...*/
 根据对象的赋值规则,可以把子类对象赋给父类对象名
父类对象名.roar()去调用时,能够根据子类对象的不同,得到不同的结果,这就是多态性。


三、抽象

抽象类指不能实例化的类,其可以包含或不包含抽象方法
抽象类生来就是为了被子类继承
抽象类与具体类的比较
抽象类具体类
用于划分具体类用于表示真实世界的对象
不能实例化可以实例化
可定义未提供实现的抽象方法不能定义未提供实现的抽象方法
可为自己的部分方法提供实现为所有方法提供实现

使用方法
//抽象类的定义格式:
    [访问权限]  abstract  class 类名{……}
    //如
        abstract class Shape {……}

//抽象方法的定义格式:
    [访问权限]  abstract  返回类型 方法名([参数表]);//无方法体
    //抽象方法举例:
        public abstract double getArea();
        public abstract double getPerimeter();
10
 
1
//抽象类的定义格式:
2
    [访问权限]  abstract  class 类名{……}
3
    //如
4
        abstract class Shape {……}
5
 
          
6
//抽象方法的定义格式:
7
    [访问权限]  abstract  返回类型 方法名([参数表]);//无方法体
8
    //抽象方法举例:
9
        public abstract double getArea();
10
        public abstract double getPerimeter();
使用注意事项(重点)
  1. 当一个类中包含有抽象方法时,该类一定要声明为抽象类
  2. 子类继承抽象类时,必须实现该抽象类中的所有抽象方法
  3. 当类实现了一个接口,但并没有实现该接口的所有方法时,该类必须声明为抽象类,否则出错
  4. 抽象方法无方法体,在缺省情况下默认为public
  5. 抽象方法不能被private、final或static修饰
    1. 抽象方法必须被子类所覆盖,所以不能用final修饰;如果说明为private,则外部无法访问,覆盖也无从谈起;若说明为static,即不创建对象也能访问:类名.方法名() ,这要求给出方法体,但与抽象方法的定义相矛盾。

四、接口

接口可以实现不相关类的相同行为, 只关注功能,不关注具体实现
一个类可以继承多个接口
接口中的方法都是抽象方法,成员变量都为静态常量

使用方法
//接口的定义——interface关键字
    [权限修饰符]  interface 接口名 [extends 父接口列表]{
	    //抽象方法和静态常量
    }
    //如
        public interface Runner {
		    int id = 1;
	    	public void start();//无方法体
	    	public void run();
	    	public void stop();
	    }

//接口的实现——implements关键字
    [修饰符]  class 类名 [extends 父类] implements 接口1[,接口2,…]{
	    ……		//包含对接口的所有方法的实现
    }
    //接口实现示例
        public class Person implements Runner{ 
        	public void start() {
	         // 准备工作:弯腰、蹬腿、咬牙、瞪眼
	         // 开跑
            }
       	}

//接口的继承——允许一个接口用extends继承另一个接口
    接口名 extends 父接口1[,父接口2,…]{
    	……		//新增的抽象方法或静态常量
    }
28
 
1
//接口的定义——interface关键字
2
    [权限修饰符]  interface 接口名 [extends 父接口列表]{
3
        //抽象方法和静态常量
4
    }
5
    //如
6
        public interface Runner {
7
            int id = 1;
8
            public void start();//无方法体
9
            public void run();
10
            public void stop();
11
        }
12
 
          
13
//接口的实现——implements关键字
14
    [修饰符]  class 类名 [extends 父类] implements 接口1[,接口2,]{
15
        ……      //包含对接口的所有方法的实现
16
    }
17
    //接口实现示例
18
        public class Person implements Runner{ 
19
            public void start() {
20
             // 准备工作:弯腰、蹬腿、咬牙、瞪眼
21
             // 开跑
22
            }
23
        }
24
 
          
25
//接口的继承——允许一个接口用extends继承另一个接口
26
    接口名 extends 父接口1[,父接口2,]{
27
        ……      //新增的抽象方法或静态常量
28
    }

使用注意事项
  1. 接口中的所有方法都是抽象的,只有声明、没有方法体
  2. 接口不可以被实例化,常作为类型使用
  3. 实现类必须实现接口的所有方法
  4. 接口中的常量默认是公共的、静态的和最终的,在声明时一般不需要用public、static、final。





转载于:https://www.cnblogs.com/walton/p/10733264.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值