Java:包、继承

本文详细介绍了Java编程中的包、继承和组合的概念及使用。包主要用于保证类的唯一性,通过package和import语句管理类。继承允许子类继承父类的特性,Java中单继承特性确保代码的稳定。组合则是实现"has-a"关系,通过组合复用代码。文章还探讨了访问权限、protected关键字和final关键字的作用。通过对这些概念的理解,开发者可以更好地组织和设计代码。
摘要由CSDN通过智能技术生成

目录

包(package)

1.包的出现

2.导入包中的类

3.将类放到包中

继承(extends)

1、基本语法

2、规则

3、四种访问权限

4、protected 关键字

5、final 关键字

组合

1、组合

2、super 关键字


包(package)

1.包的出现

  • 使用包的主要目的是保证类的唯一性。
  • 包是组织类的一种方式。

1、如图,在工程text的src中,已经有Test类,此时你在src中创建命名为Test的类时,是不允许的

       如果你在工作中代码中写了一个 Test 类,然后你的同事也可能写一个 Test 类,你要去查看他的内容时,出现两个同名的类, 就会冲突, 导致代码不能编译通过。(此时我们可以在src中创建一个包,在包中定义一个Text类是可以的。)

2、如何创建包,在包中创建类

1) 在 IDEA 中先新建一个包: 右键 src -> 新建 -> 包;

2) 输入包名(如:net.csdn.blog);

3) 在包中创建类, 右键包名 -> 新建 -> 类, 然后输入类名(如:Test)即可;

4) 此时可以看到我们的磁盘上的目录结构已经被 IDEA 自动创建出来了;

5) 同时我们也看到了, 在新创建的 Test.java 文件的最上方, 就出现了一个 package 语句。

文件夹中:


2.导入包中的类

用package声明包,用 import 语句导入包。

Java 中已经提供了很多现成的类供我们使用,如:

1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入

2. java.lang.reflect:java 反射编程包;

3. java.net:进行网络编程开发包。

4. java.sql:进行数据库开发的支持包。

5. java.util:是java提供的工具程序包。(集合类等) 非常重要

6. java.io:I/O编程开发包

1、用 toString 输出数组的内容

以下两种写法相同:

写法一:用 import 语句导入包。

import java.util.Arrays;
public class Test {
    public static void main(String[] args) {
        int[] arr={1,2,3};
        System.out.println(Arrays.toString(arr));
    }

}

写法二:使用 java.util.Date 这种方式引入 java.util 这个包中的 Date 类.

public class Test {
    public static void main(String[] args) {
        int[] arr={1,2,3};
        System.out.println(java.util.Arrays.toString(arr));
    }
}

2、如果需要使用 java.util 中的其他类, 可以使用 import java.util.* 导入until中的全部包。但是我们更建议显式的指定要导入的类名. 否则还是容易出现冲突的情况,如下编译出错:

import java.util.*;
import java.sql.*;
public class Test {
    public static void main(String[] args) {
        // util 和 sql 中都存在一个 Date 这样的类, 此时就会出现歧义, 编译出错
        Date date = new Date();
        System.out.println(date.getTime());
   }
}
// 编译出错
Error:(5, 9) java: 对Date的引用不明确
  java.sql 中的类 java.sql.Date 和 java.util 中的类 java.util.Date 都匹配

在这种情况下需要使用完整的类名。

import java.util.*;//不在这改成import java.util.Date,其他地方可能用到的不止Date。
import java.sql.*;
public class Test {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();//写完整类名
        System.out.println(date.getTime());
   }
}

 

3.将类放到包中

基本规则

  • 在文件的最上方加上一个 package 语句指定该代码在哪个包中;
  • 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式;
  • 包名要和代码路径相匹配. 例如创建 net.csdn.blog的包, 那么会存在一个对应的路径  net/csdn/blog  来存 储代码。
  • 如果一个类没有 package 语句, 则该类被放到一个默认包中。

包的访问权限控制:

       private 中的成员只能被类的内部使用,如果某个成员不包含 public 和 private 关键字, 此时这个成员可以在包内部的其他类使用, 但是不能在包外使用,也就是默认权限(default)。

  • 对于同一个包:在net.csdn 下和 net.csdn.blog 下也不算在同一个包中;

如下: Test 和 Test1 在同一个包( net.csdn.blog)中,TestDemo不在;   在Test1中定义一个变量value(图一),在Test中可以使用(图二), 在TestDemo 中不可使用(图三),因为 value 在  net.csdn.blog.Test1  中不是公共的, 无法从外部程序包中对其进行访问)。

          

封装:将字段或者方法使用private进行修饰。其意义在于安全性,让类的调用者对类的使用成本降低。

 

 

继承(extends)

1、基本语法

class 子类 extends 父类 {

}

2、规则

1、A extends B    A:父类、超类、基类    B:子类、派生类

2、使用 extends 指定父类:

  • Java 中一个子类只能继承一个父类 (而C++/Python等语言支持多继承)。
  • 子类会继承父类的所有 public 的字段和方法,除了构造方法。
  • 对于父类的 private 的字段和方法, 子类可以继承但是无法访问的。
  • 子类的实例中, 也包含着父类的实例,可以使用 super 关键字得到父类实例的引用。
  • 对于父类的 private 的字段和方法, 子类中是无法访问的。

3、意义:代码的重复使用

4、什么时候把关系设置为继承?关系:A is a B.(Dog is a Animal.)

例:

class Animal{
    public String name;
    public String age;

    public void eat(){
        System.out.println("吃");
    }
}
class Dog {
    public String name;
    public String age;

    public void eat() {
        System.out.println("吃");
    }
}
class Bird {
    public String name;
    public String age;

    public void eat() {
        System.out.println("吃");
    }

    public void fly() {
        System.out.println("飞");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog=new Dog();
        dog.name="灰灰";
        dog.eat();

        Bird bird=new Bird();
        bird.name="八哥";
        bird.eat();
        bird.fly();

    }
}
//灰灰吃
  八哥吃
  八哥飞

运用继承后:

class Animal{
    public String name;
    public String age;

    public void eat(){
        System.out.println("吃");
    }
}
class Dog extends Animal {
}

class Bird extends Animal {
    public void fly() {
        System.out.println("飞");
    }
}
public class Test {
    public static void main(String[] args) {
       Dog dog=new Dog();
        dog.name="灰灰";
        dog.eat();

        Bird bird=new Bird();
        bird.name="八哥";
        bird.eat();
        bird.fly();
    }
}
//灰灰吃
  八哥吃
  八哥飞

 

3、四种访问权限

Java 中对于字段和方法共有四种访问权限:

  • private: 类内部能访问, 类外部不能访问
  • 默认(也叫包访问权限): 类内部能访问, 同一个包中的类可以访问, 其他类不能访问.
  • protected: 类内部能访问, 子类和同一个包中的类可以访问, 其他类不能访问.
  • public : 类内部和类的调用者都能访问。

   

4、protected 关键字

如果把字段设为 private, 子类不能访问,但是设成 public, 又违背了我们 "封装" 的初衷。两全其美的办法就是 protected 关键字:

对于类的调用者来说, protected 修饰的字段和方法是不能访问的; 

对于类的 子类 和 同一个包 的其他类 来说, protected 修饰的字段和方法是可以访问的。

用protected修饰的变量:

  • 同一类可访问
  • 同包不同类可访问
  • 不同包需继承才可访问(如下示例)

Test1与TestDemo在不同的包中(看目录),Test1在 net.csdn.blog包下,TestDemo在src下,在Test1中 定义一个用protected修饰的变量val,当 TestDemo 继承 Test1时,通过super.val 是可以访问的。

 

5、final 关键字

 final 关键字, 修饰一个变量或者字段的时候, 表示 常量 (不能修改)。

final 关键字也能修饰类, 此时表示被修饰的类就不能被继承。

final public class Animal {
 ...
}
public class Bird extends Animal {
 ...
}
// 编译出错
Error:(3, 27) java: 无法从最终com.bit.Animal进行继承

组合

1、组合

和继承类似, 组合也是一种表达类之间关系的方式, 也是能够达到代码重用的效果.例如表示一个学校:

public class Student {
 ...
}
public class Teacher {
 ...
}
public class School {
 public Student[] students;
 public Teacher[] teachers;
} 

组合表示 has - a 语义 在刚才的例子中, 我们可以理解成一个学校中 "包含" 若干学生和教师.

继承表示 is - a 语义 在上面的 "动物和猫" 的例子中, 我们可以理解成一只猫也 "是" 一种动物

2、super 关键字

this代表当前对象的引用

  • this():调用自己的构造方法
  • this.func():访问方法
  • this.data:访问属性

1、super:父类对象的引用

2、用法:

1. 使用了 super 来调用父类的构造器

  • 子类继承父类,子类构造的时候,需要首先帮助父类进行构造。
  • 怎么帮助父类构造?在子类的构造方法内部,调用父类的构造方法:super()//显式调用父类的构造方法。所以构造方法不是被继承的,二是在子类显式被调用的。

2.使用 super 来调用父类的普通方法

class Animal{
    public String name;
    public Animal(String name) {
        this.name = name;
    }
    public void eat(String food){

    }
}
class Bird extends Animal {
    public Bird(String name) {
        super(name);
    }

    @Override
    public void eat(String food) {
        // 修改代码, 让子调用父类的接口
        super.eat(food);
        System.out.println("我是一只小鸟");
        System.out.println(this.name + "正在吃" + food);
    }
}

public class TestDemo {
    public static void main(String[] args) {
        Bird bird=new Bird("Lucky");
        bird.eat("baba");
    }
}
//
我是一只小鸟
Lucky正在吃baba

1.子类构造首先帮助父类构造对象(从运行结果看出,是先帮助父类构造,然后子类构造)

class Animal{
    public String name;
    private int age;

    //构造函数
    public Animal(){//不含参数
        super();//默认会有可以不写
        System.out.println("父类构造(不带参数)");
    }
    public Animal(String name, int age) {//两个参数
        this.name = name;
        this.age = age;
        System.out.println("Animal(String,int)");
    }
}
class Dog extends Animal{
    //构造方法
    public Dog() {
        super();//默认会有,可以不写
        System.out.println("子类构造(不带参数)");
    }

    public Dog(String name, int age) {
        super(name, age);
        System.out.println("Dog(String,int)");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Dog dog=new Dog();// 不带参数
    }
}
//结果:
父类构造(不带参数)
子类构造(不带参数)

2.如何帮助?(通过super()调用父类的造方法)。

          

3.父类无构造方法,默认会有一个不带参数的构造方法,此时以下写法是正确的;

4.但是当父类的构造方法带有参数时,就不会默认生成不带有参数的构造方法,此时子类也不需要帮助父类构造不含参数的构造方法。

5.注:

  • super()放在第一行!

  • super不能在静态方法当中使用(super代表父类对象的引用,而静态的不依赖对象)

6、注意 super 和 this 功能相似, 但有区别

7.执行顺序:静态的先执行且只执行一次;

class Animal{
    public String name;
    private int age;
    static {
        System.out.println("父类静态代码块");
    }
    {
        System.out.println("父类实例代码块");
    }
    public Animal(){//构造方法
        System.out.println("父类构造");
    }
}
class Dog extends Animal{
    static {
        System.out.println("Dog静态代码块");
    }
    {
        System.out.println("Dog实例代码块");
    }
    public Dog() {//构造方法
        super();//默认会有,可以不写
        System.out.println("Dog构造");
    }
}
class Bird extends Animal{
    static {
        System.out.println("Bird静态代码块");
    }
    {
        System.out.println("Bird实例代码块");
    }
    public Bird() {//构造方法
        System.out.println("Bird构造");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Dog dog=new Dog();
        System.out.println("------------");
        Bird brid=new Bird();
    }
}

运行结果分析:

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值