JAVA面向程序设计三大特征

目录

一、面向对象与面向过程

二、封装(Encapsulation)

1、权限修饰符:(常使用private、public)

2、JAVA封装

三、继承(Extends)

1、继承

2、继承中成员访问特点

3、重写与重载

四、多态(Polymorphism)

1、多态的定义

2、多态的前提

3、多态的成员访问特点

4、多态的好处与弊端

5、多态的转型


一、面向对象与面向过程

面向过程强调的是功能行为,而面向对象强调的是具备功能的对象。面向过程程序设计,强调把”事情“当作核心,就像我们在前往某个地方时,如何前往、路线计划是什么、到达目的地后做什么,分成步骤来完成我们这件事情,在编程中各个具体的步骤就是一个个的函数。而面向对象程序设计则强调把”对象“当作核心,像是无需多虑直接滴滴打车,只需要告诉司机你的目的地就可以了,把人、事物看作一个对象,每一个对象都有自己的属性与行为,建立多个对象来解决整一个的问题而非分步解决。相较于面向过程,在完成某件任务时,我们不再像是一个执行者,而更像是一个指挥者。   由于面向对象具有封装,继承和多态的特性,因此面向对象的程序设计具有易维护,易扩展,易复用的优点。

二、封装(Encapsulation)

1、权限修饰符:(常使用private、public)

private只能在当前类中访问
default只能在当前包内访问
protected只能在当前包与其派生包内访问
public谁都能访问

下面一段代码作为protected权限修饰符的应用展示:

/**
 * @author Tweek
 */
public class Father {
    /**
        父类中的方法
    */
    protected void method(){
        System.out.println("U know I'm ur Father!");
    }
}
/**
     不同包下的子类
*/
import a.Father
public class Son extends Father {
    /**
         不同包下的子类可以访问父类在protected修饰下的方法,并继承该方法。
         用super来调用
    */
    @Override
    public void method() {
        super.method();
    }
​
}
​
/**
   测试类与子类在一个包内,但与父类无关,不是父类的派生类
*/
public class Test {
    public static void main(String[] args) {
        Son son = new Son();
        /**
            此时Test类中创建一个同包下的类的对象,调用同包下类的方法method
            来到Son类中发现method内容需要super来调用
            此时通过Son与Father的继承关系,Son用super调用了不同包下的Father中用protected修饰的方法
            若Son中无super调用
            Son类作为Father类的派生类可调用不同包下Father中用protected修饰的方法,而Test却不可通过Son对象来调用Son中的method方法,因为此时Son类中的method方法相当于Father类中的method方法,故Test作为Father不同包下的无关类,无法调用method方法。
        */
        son.method();
    }
}
​
控制台输出:
U know I'm ur Father!

2、JAVA封装

JAVA的封装一般是通过private修饰符来声明属性和方法实现的。

下面展示一段代码(JAVABEAN)体现数据封装:

public class Student {
    private int age;          //private封装属性age
    private String name;      //private封装属性name
​
    public Student() {
    }
​
    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
​
    public int getAge() {                //用于获取属性age
        return age;
    }
​
    public void setAge(int age) {        //用于设置属性age
        this.age = age;
    }
​
    public String getName() {            //用于获取属性name
        return name;
    }
​
    public void setName(String name) {   //用于设置属性name
        this.name = name; 
    }
}
/** 
    测试类
*/
public class Test(){
      public static void main(String[] args) {
         Student stu = new Student(21,"Tweek");   //Student(age,name)
         System.out.println(stu.getName() + "   " + stu.getAge());
      }
}
​
控制台输出:
21      Tweek

三、继承(Extends)

1、继承

(1)关于继承的描述

继承所关联的有两种类,父类子类,在继承关系中,应用继承所创建的新类称为子类,被继承的类称为父类。子类通过extends关键字来进行继承这一行为,产生继承关系后,子类会继承父类的属性行为,由此可以扩展新的能力。

(2)继承的优点

1.继承使得代码更加简洁

2.提高代码复用性维护性

(3)继承的特点

JAVA只支持单继承、不支持多继承,但支持多层继承

2、继承中成员访问特点

(1)成员变量

1.this:调用当前类中的成员变量

2.super:调用当前类的父类中的成员变量

3.在方法内出现与当前类成员变量相同的局部变量,若调用变量且无修饰词修饰变量,根据优先原则,优先调用局部变量

下面是代码示例:

/**
 * @author Tweek
 */
public class ExtendsTest1 {
    int age = 30;
​
    public static void main(String[] args) {
        Son son = new Son();
        son.method();
    }
}
class Son extends ExtendsTest1{
    int age =20;
    public void method(){
        int age =19;
        System.out.println(age);
        System.out.println(this.age);
        System.out.println(super.age);
​
    }
}
​
控制台输出:
19
20
30

(2)成员方法访问特点

若在子类与父类中出现了方法声明一模一样的方法,在创建子类对象并调用其方法时,方法调用优先调用子类中的方法,这一操作称为方法重写。

下面是代码示例:

/**
 * @author Tweek
 */
public class ExtendsTest1 {
    int age = 30;
    public void show(){
        System.out.println("I'm Father");
    }
    public static void main(String[] args) {
        Son son = new Son();
        son.show();
    }
}
class Son extends ExtendsTest1{
    @Override
    public void show() {
        System.out.println("I'm Son");
    }
}
​
控制台输出:
I'm Son

3、重写与重载

(1)重写(Override)

在父类与子类中,出现了一模一样方法声明的方法(方法名,参数,返回值),此时在继承关系中,子类方法重写父类方法,调用子类方法为优先逻辑

当子类需要父类的方法而父类的方法不适用在当前情景中,子类重写父类方法可以对父类方法进行修改增强操作

注意:1.父类中private方法不能被重写

2.子类重写父类方法时,访问权限必须大于等于父类

(2)重载(Overload)

在同一个类中,方法名相同参数不同(类型不同、个数不同、顺序不同),与返回值无关,则称方法重载

下面展示有关重载代码:

/**
 * @author Tweek
 */
public class ExtendsTest1 {
    int age = 30;
    public void show(){
        System.out.println("I'm Father");
    }
    public static void main(String[] args) {
        Son son = new Son();
        son.show();
    }
}
class Son extends ExtendsTest1{
/*
         方法名相同,参数不同,出现方法重载
*/
    public void show(int num) {
        System.out.println("I'm Son");
    }
}
​
控制台输出:
I'm father

四、多态(Polymorphism)

1、多态的定义

同一种行为具有多个不同表现形式或形态的能力。通俗点来说,就好比两个人都会唱歌,但是一个人擅长民族歌曲,另一个人擅长流行歌曲,在校园歌手大赛上,两个都会唱歌的人,却选择了风格迥异的歌曲了进行演唱这一行为。

2、多态的前提

(1)前提

1.有继承实现关系

2.有方法重写

3.有父类引用指向子类对象

(2)多态的形式

满足前提条件后,代码可以产生两种类型的多态:

1.对象多态:方法的形参定义为父类类型,这个方法可以接受到父类的任意子类对象。如从本小节代码示例中的部分截取。

Singer tweek = new Tweek();
  Singer jim = new Jim();

2.行为多态:同一个方法,具有多种不同表现形式,或形态的能力。

下面代码示例,能让我们更好地理解:

/**
 * @author Tweek
 */
public abstract class Singer {
    /**
     * People who can sing
     */
    public abstract void sing();
}
​
public class Tweek extends Singer{
    /**
     * The one who can sing The Pop Music
     */
    @Override
    public void sing() {
        System.out.println("I'm Tweek and I'm good at the pop music!");
    }
}
​
public class Jim extends Singer {
    /**
     * The one who can sing The Ethnic Music
     */
    @Override
    public void sing() {
        System.out.println("I'm Jim and I'm good at the ethnic music!");
    }
}
​
public class Test3 {
    /**
        测试类
    */
    public static void main(String[] args) {
        Singer tweek = new Tweek();
        Singer jim = new Jim();
        tweek.sing();
        jim.sing();
    }
}
​
控制台输出:
I'm Jim and I'm good at the ethnic music!
I'm Tweek and I'm good at the pop music!

3、多态的成员访问特点

(1)成员变量

编译阶段看父类,运行阶段也是看父类。即编译阶段在父类中寻找成员变量,运行阶段以父类的成员变量运行。

(2)成员方法

编译阶段看父类,运行阶段看子类。即编译阶段寻找父类中的方法,子类继承并重写了父类的方法,故运行阶段走子类的方法逻辑。

下面是代码示例:

/**
 * @author Tweek
 */
public abstract class Singer {
    /**
     * People who can sing
     */
    public abstract void sing(); //父类中的方法
    int num =20;  //父类中的成员变量
}
​
public class Tweek extends Singer{
    /**
     * The one who can sing The Pop Music
     */
    @Override
    public void sing() {
        System.out.println("I'm Tweek and I'm good at the pop music!");    //子类继承并重写了父类的方法
    }
    int num =30;     //子类中的成员变量
}
​
public class Test3 {
    /**
    *  测试类
    */
    public static void main(String[] args) {
        Singer tweek = new Tweek();   //对象多态
        tweek.sing();   //行为多态
        System.out.println("num: "+tweek.num);
    }
}
​
控制台输出:
I'm Tweek and I'm good at the pop music!
num: 20

4、多态的好处与弊端

(1)多态的好处

提高了程序的扩展性。即对象多态、行为多态的支持,同一个方法不同的形态。

(2)多态的弊端

不能使用子类的特有成员变量、方法

解决方法:利用多态的向下转型,调用子类中特有的成员变量、方法

5、多态的转型

(1)向上转型(Upcasting)

多态的向上转型,即父类引用指向子类对象(从子类到父类)。子类重写父类中的方法,通过父类引用指向子类对象,调用子类中的重写父类的方法。

代码示例(父类Singer,子类Tweek):

Singer tweek = new Tweek();

(2)向下转型(Downcasting)

将父类引用所指向的对象,转交给子类类型,即父类到子类。当父类创建对象实现子类多态时,因无法调用子类的特有成员,故此时需向下转型将实现的子类多态转交给子类类型,从而实现调用。此种转型需要强转型

代码示例:

Tweek t = (Tweek)tweek;

(3)类型转换错误异常(ClassCastException)

出现异常的原因:在引用类型的强转中,实际类型目标类型不匹配。

解决方法:

添加判断:判断类型是否匹配,在if语句中用instanceof判断(判断左边引用,是否是右边的数据类型)。

instanceof是Java中的二元运算符,作用是测试它左边的对象是否是它右边的类的实例,返回 boolean数据类型。当左边的对象是右边的类或子类所创建的对象时,返回true,否则,返回false。

下面的代码展示了可能会出现错误的情况:

Singer tweek = new Tweek();
Singer jim = new Jim();
Tweek t = (Tweek)tweek;
Tweek j =(Tweek)jim;
/**
    在运行过程中第四行代码报错并抛出异常java.lang.ClassCastException。
    tweek与jim都是Singer创建的对象,虽然第三、四行代码几乎相同,都是把Singer强制转换为Tweek,第三行代码的意思是把擅长流行乐的歌手Tweek转换为Tweek本身,第四行代码的意思是把擅长民乐的歌手Jim转化为Tweek本身,但Tweek会的技能,Jim不一定会或是根本不会,故此处产生了实际类型与目标类型不匹配。
*/

下面的代码展示在具体场景中的instance应用: 

/**
 * @author Tweek
 */
public class Tweek extends Singer{
    /**
     * The one who can sing The Pop Music
     */
    @Override
    public void sing() {
        System.out.println("I'm Tweek and I'm good at the pop music!");
    }
    /**
       Tweek子类的特有方法hobby()
    */
    public void hobby(){
        System.out.println("I'm Tweek and I like playing basketball!");
    }
}
​
public class Jim extends Singer {
    /**
     * The one who can sing The Ethnic Music
     */
    @Override
    public void sing() {
        System.out.println("I'm Jim and I'm good at the ethnic music!");
    }
}
​
public class Test3 {
    /**
     * 测试类
     */
    public static void main(String[] args) {
       Singer singer = null;
        Scanner in = new Scanner(System.in);
        System.out.println("1.The Pop music Singer Tweek");
        System.out.println("1.The Ethnic music Singer Jim");
        System.out.print("请选择你想要的歌手:");
       int choice = in.nextInt();
        /**
         * 选择你想要的歌手
         */
       switch (choice){
           case 1:
               singer = new Tweek();
               break;
           case 2:
               singer = new Jim();
               break;
           default:
               System.out.println("无此歌手!");
               break;
       }
        System.out.println("歌手自我介绍:");
       if(singer instanceof Tweek){
           Tweek tweek = (Tweek)singer;  //向下转型
           tweek.hobby();  //调用子类特定的方法
       }
       singer.sing();
    }
}
​
第一次控制台输出:
1.The Pop music Singer Tweek
1.The Ethnic music Singer Jim
请选择你想要的歌手:1
歌手自我介绍:
I'm Tweek and I like playing basketball!
I'm Tweek and I'm good at the pop music!
    
第二次控制台输出:
1.The Pop music Singer Tweek
1.The Ethnic music Singer Jim
请选择你想要的歌手:2
歌手自我介绍:
I'm Jim and I'm good at the ethnic music!

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值