Java面向对象编程(进阶)一

本文详细介绍了Java编程中的关键概念,包括包和import的使用、封装性、this关键字的应用、继承机制、方法的重写与重载。通过实例阐述了如何在实践中运用这些核心原理。
摘要由CSDN通过智能技术生成

在众多编程语言中,Java作为一种广泛应用的高级编程语言,以其强大的面向对象特性和跨平台性能而备受开发者青睐。本文将深入探讨Java面向对象编程的核心概念、特点以及应用实践。

目录

1、关键字:package、import

1.1 package包

1.1.1 语法格式

1.1.2 包的作用

1.1.3  JDK中主要的包介绍

1.2 import(导入)

1.2.1 语法格式

1.2.2 注意事项

2、封装性 (encapsulation)

2.1 何为封装性

2.2 Java如何实现数据封装

2.3 封装性的体现

3、关键字:this

3.1 this是什么

3.2 什么时候使用this

3.2.1 实例方法或构造器中使用当前对象的成员

3.2.2 同一个类中构造器互相调用

4、继承(Inheritance )

4.1 继承的概述

4.2 继承的语法

4.2.1 继承中的语法格式

4.2.2 继承中的基本概念 

4.3 继承性的细节说明 

5、方法的重写 (override/overwrite )

5.1 方法重写示例

5.2 方法重写的要求 

5.3 方法的重载与重写


 

1、关键字:package、import

1.1 package包

package,称为包,用于指明该文件中定义的类、接口等结构所在的包。

1.1.1 语法格式

package 顶层包名.子包名 ;

示例

package pack1.pack2; //指定类PackageTest属于包pack1.pack2

public class PackageTest{
    public void display(){
        System.out.println("in method display()");
    }
}

说明:
1、 一个源文件只能有一个声明包的package语句
2、package语句作为Java源文件的第一条语句出现。若缺省该语句,则指定为无名包。
3、包名,属于标识符,满足标识符命名的规则和规范(全部小写)、见名知意
          包通常使用所在公司域名的倒置:com.atguigu.xxx。
          大家取包名时不要使用" java.xx "包
4、包对应于文件系统的目录,package语句中用 “.” 来指明包(目录)的层次,每.一次就表示一层文件目录。
5、同一个包下可以声明多个结构(类、接口),但是不能定义同名的结构(类、接口)。不同的包下 可以定义同名的结构(类、接口)

1.1.2 包的作用

1、包可以包含类和子包,划分 项目层次 ,便于管理
2、帮助 管理大型软件 系统:将功能相近的类划分到同一个包中。比如:MVC的设计模式
3、解决 类命名冲突 的问题
4、控制 访问权限

1.1.3  JDK中主要的包介绍

java.lang ----包含一些Java语言的核心类,如String、Math、Integer、 System和Thread,提供常用功能
java.net ----包含执行与网络相关的操作的类和接口。
java.io ----包含能提供多种输入/输出功能的 类。
java.util ----包含一些实用工具类,如定义系统特性、接口的集合框架类、使用与日期日历相关 的函数
java.text ----包含了一些java格式化相关的类
java.sql ----包含了java进行JDBC数据库编程 的相关类/接口
java.awt ----包含了构成抽象窗口工

1.2 import(导入)

 为了使用定义在其它包中的Java类,需用import语句来显式引入指定包下所需要的类。相当于 import语 句告诉编译器到哪里去寻找这个类 。

1.2.1 语法格式

import 包名.类名;
示例:

import pack1.pack2.Test; //import pack1.pack2.*;表示引入pack1.pack2包中的所有结构

public class PackTest{
    public static void main(String args[]){
        Test t = new Test(); //Test类在pack1.pack2包中定义
        t.display();
    }
}

1.2.2 注意事项

1、import语句,声明在包的声明和类的声明之间。
2、如果需要导入多个类或接口,那么就并列显式多个import语句即可
3、如果使用 a.* 导入结构,表示可以导入a包下的所有的结构。举例:可以使用java.util.*的方式,一 次性导入util包下所有的类或接口。
4、如果导入的类或接口是java.lang包下的,或者是当前包下的,则可以省略此import语句。
5、如果已经导入java.a包下的类,那么如果需要使用a包的子包下的类的话,仍然需要导入。
6、如果在代码中使用不同包下的同名的类,那么就需要使用类的全类名的方式指明调用的是哪个类。
7、(了解) import static 组合的使用:调用指定类或接口下的静态的属性或方法


2、封装性 (encapsulation)

2.1 何为封装性

所谓封装,就是把客观事物封装成抽象概念的类,并且类可以把自己的数据和方法只向可信的类或者对 象开放,向没必要开放的类或者对象隐藏信息。

2.2 Java如何实现数据封装

实现封装就是控制类或成员的可见性范围。这就需要依赖访问控制修饰符,也称为权限修饰符来控 制。
权限修饰符: public 、 protected 、 缺省 、 private 。

修饰符本类内部本包内其他包的子类其他非包子类
private×××
缺省××
protected×
public

2.3 封装性的体现

2.3.1 成员变量/属性私有化

 私有化类的成员变量,提供公共的get和set方法,对外暴露获取和修改属性的功能。
1、使用private修饰成员变量
private 数据类型 变量名 ;

public class Person {
    private String name;
    private int age;
    private boolean marry;
}

2、提供 getXxx方法/setXxx方法,可以访问成员变量

public class Person {
    private String name;
    private int age;
    private boolean marry;
    
    public void setName(String n) {
        name = n;
    }

    public String getName() {
        return name;
    }

    public void setAge(int a) {
        age = a;
    }

    public int getAge() {    
        return age;
    }

    public void setMarry(boolean m){
        marry = m;
    }

    public boolean isMarry(){
        return marry;
    }
}

3、测试

public class PersonTest {
    public static void main(String[] args) {
        Person p = new Person();

        p.setName("张三");
        System.out.println("p.name = " + p.getName());

        p.setAge(23);
        System.out.println("p.age = " + p.getAge());

        p.setMarry(true);
        System.out.println("p.marry = " + p.isMarry());
    }
}

成员变量封装的好处:
1、让使用者只能通过事先预定的方法来 访问数据 ,从而可以在该方法里面加入控制逻辑,限制对成员 变量的不合理访问。还可以进行数据检查,从而有利于保证对象信息的完整性。
2、便于修改 ,提高代码的可维护性。主要说的是隐藏的部分,在内部修改了,如果其对外可以的访问 方式不变的话,外部根本感觉不到它的修改。


3、关键字:this

3.1 this是什么

  • 它在方法(准确的说是实例方法或非static的方法)内部使用,表示调用该方法的对象
    它在构造器内部使用,表示该构造器正在初始化的对象。
  • this可以调用的结构:成员变量、方法和构造器

3.2 什么时候使用this

3.2.1 实例方法或构造器中使用当前对象的成员

在实例方法或构造器中,如果使用当前类的成员变量或成员方法可以在其前面添加this,增强程序的可读性。不过,通常我们都习惯省略this。

但是,当形参与成员变量同名时,如果在方法内或构造器内需要使用成员变量,必须添加this来表明该变量是类的成员变量。即:我们可以用this来区分成员变量局部变量

3.2.2 同一个类中构造器互相调用

this可以作为一个类中构造器相互调用的特殊格式。

  • this():调用本类的无参构造器

  • this(实参列表):调用本类的有参构造器

public class Student {
    private String name;
    private int age;

    // 无参构造
    public Student() {
        this("",18);//调用本类有参构造器
    }

    // 有参构造
    public Student(String name) {
        this();//调用本类无参构造器
        this.name = name;
    }
    // 有参构造
    public Student(String name,int age){
        this(name);//调用本类中有一个String参数的构造器
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public String getInfo(){
        return "姓名:" + name +",年龄:" + age;
    }
}

注意:
 

 不能出现递归调用。比如,调用自身构造器。
        推论:如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了"this(形参列表)"
this()和this(实参列表)只能声明在构造器首行。
        推论:在类的一个构造器中,最多只能声明一个"this(参数列表)"


4、继承(Inheritance )

4.1 继承的概述

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类中无需再定义这些属性和行为,只需要和抽取出来的类构成继承关系

继承的好处:
继承的出现减少了代码冗余,提高了代码的复用性。
继承的出现,更有利于功能的扩展。
继承的出现让类与类之间产生了is-a的关系,为多态的使用提供了前提。

4.2 继承的语法

4.2.1 继承中的语法格式

通过 extends 关键字,可以声明一个类B继承另外一个类A,定义格式如下:

[修饰符] class 类A {
	...
}

[修饰符] class 类B extends 类A {
	...
}

4.2.2 继承中的基本概念 

类B,称为子类、派生类(derived class)、SubClass
类A,称为父类、超类、基类(base class)、SuperClass

示例:
1、父类

/*
 * 定义动物类Animal,做为父类
 */
public class Animal {
    // 定义name属性
    String name;
    // 定义age属性
    int age;

    // 定义动物的吃东西方法
    public void eat() {
        System.out.println(age + "岁的"
                + name + "在吃东西");
    }
}

2、子类

/*
 * 定义猫类Cat 继承 动物类Animal
 */
public class Cat extends Animal {
    int count;//记录每只猫抓的老鼠数量

    // 定义一个猫抓老鼠的方法catchMouse
    public void catchMouse() {
        count++;
        System.out.println("抓老鼠,已经抓了"
                + count + "只老鼠");
    }
}

3、测试类

public class TestCat {
    public static void main(String[] args) {
        // 创建一个猫类对象
        Cat cat = new Cat();
        // 为该猫类对象的name属性进行赋值
        cat.name = "Tom";
        // 为该猫类对象的age属性进行赋值
        cat.age = 2;
        // 调用该猫继承来的eat()方法
        cat.eat();
        // 调用该猫的catchMouse()方法
        cat.catchMouse();
        cat.catchMouse();
        cat.catchMouse();
    }
}

4.3 继承性的细节说明 

1、子类会继承父类所有的实例变量和实例方法
2、子类不能直接访问父类中私有的(private)的成员变量和方法
3、在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集,而是对父类的“扩展”
4、Java支持多层继承(继承体系)
5、一个父类可以同时拥有多个子类
6、Java只支持单继承,不支持多重继承


5、方法的重写 (override/overwrite )

子类可以对从父类中继承来的方法进行改造,我们称为方法的重写 (override、overwrite)。也称为方法的重置覆盖

5.1 方法重写示例

新的手机增加来电显示头像的功能,代码如下:

public class Phone {
    public void sendMessage(){
        System.out.println("发短信");
    }
    public void call(){
        System.out.println("打电话");
    }
    public void showNum(){
        System.out.println("来电显示号码");
    }
}
//SmartPhone:智能手机
public class SmartPhone extends Phone{
    //重写父类的来电显示功能的方法

    public void showNum(){
        //来电显示姓名和图片功能
        System.out.println("显示来电姓名");
        System.out.println("显示头像");
    }
    //重写父类的通话功能的方法

    public void call() {
        System.out.println("语音通话 或 视频通话");
    }
}
public class TestOverride {
    public static void main(String[] args) {
        // 创建子类对象
        SmartPhone sp = new SmartPhone();

        // 调用父类继承而来的方法
        sp.call();

        // 调用子类重写的方法
        sp.showNum();
    }
}

5.2 方法重写的要求 

1、子类重写的方法必须和父类被重写的方法具有相同的方法名称参数列表
2、子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型。(例如:Student < Person)。

注意:如果返回值类型是基本数据类型和void,那么必须是相同

 3、子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限。(public > protected > 缺省 > private)

注意:① 父类私有方法不能重写 ② 跨包的父类缺省的方法也不能重写

 4、子类方法抛出的异常不能大于父类被重写方法的异常

此外,子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。

5.3 方法的重载与重写

方法的重载:方法名相同,形参列表不同。不看返回值类型。

方法的重写:子类可以对从父类中继承来的方法进行改造

1、同一个类中

public class TestOverload {
    public int max(int a, int b){
        return a > b ? a : b;
    }
    public double max(double a, double b){
        return a > b ? a : b;
    }
    public int max(int a, int b,int c){
        return max(max(a,b),c);
    }
}

2、父子类中

public class TestOverloadOverride {
    public static void main(String[] args) {
        Son s = new Son();
        s.method(1);//只有一个形式的method方法

        Daughter d = new Daughter();
        d.method(1);
        d.method(1,2);//有两个形式的method方法
    }
}

class Father{
    public void method(int i){
        System.out.println("Father.method");
    }
}
class Son extends Father{
    public void method(int i){//重写
        System.out.println("Son.method");
    }
}
class Daughter extends Father{
    public void method(int i,int j){//重载
        System.out.println("Daughter.method");
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值