JAVA里的面向对象编程

JAVA里的面向对象编程

**1、包
**包(package)是组织类的一种方式,使用包的目的是保证类的唯一性
可以使用java.util.data这种方式引入java.util这个包中的data类(也可以使用import导入包)。

public class Test{
    
    
    public static void main(String[] args){
    
    
    java.util.Date date=new java.util.Data();
    //得到一个毫秒级别的时间戳
    System.out.println(date.getTime());
    }
 }

或者:

import java.util.Data;
public class Test{
    
    
    public static void main(String[] args){
    
    
    Date date=new Date;
    System.out.println(date.getTime());
    }
 }

如果需要使用 java.util 中的其他类, 可以使用 import java.util.

import java.util.*;
public class Test {
    
    
    public static void main(String[] args) {
    
    
        Date date = new Date();
        // 得到一个毫秒级别的时间戳
        System.out.println(date.getTime());
   }
}

最好使用指定的要导入的类名,防止出现冲突,如下:

import java.util.*;
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());
   }
}

注意事项: import 和 C++ 的 #include 差别很大. C++ 必须 #include 来引入其他文件内容, 但是 Java 不需要.
import 只是为了写代码的时候更方便. import 更类似于 C++ 的 namespace 和 using

静态导入
使用 import static 可以导入包中的静态的方法和字段。

import static java.lang.System.*;
public class Test {
    
    
    public static void main(String[] args) {
    
    
        out.println("hello");
   }
}

将类放到包中
基本规则:
在文件的最上方加上一个 package 语句指定该代码在哪个包中.
包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例com.bit.demo1 )
包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存储代码.
如果一个类没有 package 语句, 则该类被放到一个默认包中.
操作步骤

  1. 在 IDEA 中先新建一个包: 右键 src -> 新建 -> 包
  2. 在弹出的对话框中输入包名
  3. 在包中创建类,右键包名-》新建-》类,输入类名即可
    包的访问权限控制
    private 中的成员只能被类的内部使用.
    如果某个成员不包含 public 和 private 关键字, 此时这个成员可以在包内部的其他类使用, 但是不能在包外部的类使用.

    常见的系统包
  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编程开发包。

2、继承
Animal这样被继承的类称为父类、基类或超类,cat、bird这样的类称为子类派生类,子类会继承父类的字段和方法,以达到代码重用的效果。
基本语法:
使用extends指定父类;
一个子类只能继承一个父类
子类会继承父类的所有public 的字段和方法
子类无法访问父类的private的字段和方法
子类的实例中也包含父类的实例,可以用Super关键字得到父类实例的引用
如下:

class Animal{
    
    
    public String name;
    public Animal(String name){
    
    
        this.name=name;
    }
    public void eat(String food){
    
    
        System.out.println(this.name+"正在吃"+food);
        }
    }
    class  Cat extends Animal{
    
    
    public Cat(String name){
    
    
        //使用super调用父类的构造方法
        Super(name);
        }
    }
    class bird extends Animal{
    
    
         public Bird(String name){
    
    
             super(name);
            }
    public void fly(){
    
    
        System.out.println(this.name+"正在飞");
        }
    }
    public class Test{
    
    
        public static void main(String[] args){
    
    
        Cat cat=newCat("小黑");
        cat.eat("猫粮");
        Bird bird=new Bird;
        bird.fiy();
        }
      }
        
        ```
若把name改为private,那么此时子类不能访问,如下:

```java
class Bird extends Animal{
    
    
    public Bird(String name){
    
    
         super(name);
       }
    public void fly(){
    
    
        System.out.println(this.name+"正在飞");
        }
    }
 //编译出错,name在Animal中是private访问控制。

protected关键字
对于类的调用者来说,protected修饰的字段和方法是不能访问的;
对于类的子类和同一个包的其他类来说,protected修饰的方法和字段可以访问
如下图:
在这里插入图片描述

final关键字
曾经我们学习过 final 关键字, 修饰一个变量或者字段的时候, 表示 常量 (不能修改)
final 关键字也能修饰类, 此时表示被修饰的类就不能被继承.

多态
Bird bird=new Bird(“圆圆”);也可以这样写:
Bird bird=new Bird(“圆圆”);
Animal bird2=bird;
//或者写成下面这种形式
Animal bird2=new Bird(“圆圆”);
此时bird2是一个父类Animal的引用,指向一个子类(bird)的实例,称为:向上转型

向上转型发生的时机:
直接赋值
方法传参
方法返回

动态绑定
在Java中调用某个类的方法,要看究竟这个引用的是指向的是父类对象还是子类对象,这个决定是程序运行时决定的,而不是编译期,因此称为动态绑定

方法重写
子类实现父类的同名方法, 并且参数的类型和个数完全相同, 这种情况称为 覆写/重写/覆盖(Override).
关于重写的注意事项

  1. 重写和重载完全不一样. 不要混淆
  2. 普通方法可以重写, static 修饰的静态方法不能重写
  3. 重写中子类的方法的访问权限不能低于父类的方法访问权限.
  4. 重写的方法返回值类型不一定和父类的方法相同(但是建议最好写成相同, 特殊情况除外)
  5. 针对重写的方法,可以使用@override注解来显示指定

小结:重载与重写的区别在这里插入图片描述
向下转型
向上转型是子类对象转成父类对象, 向下转型就是父类对象转成子类对象. 相比于向上转型来说, 向下转型没那么常见,但是也有一定的用途.

super关键字
子类内部调用父类方法可以调用super关键字

  1. 使用了 super 来调用父类的构造器
  2. 使用 super 来调用父类的普通方法
    在这里插入图片描述
    抽象类
    包含抽象方法的类我们称为 抽象类
    对于包含抽象方法的类, 必须加上 abstract 关键字表示这是一个抽象类.
    注意事项
    1)抽象类不能直接实例化
    Shape shape = new Shape();
    // 编译出错
    Error:(30, 23) java: Shape是抽象的; 无法实例化
    2 抽象方法不能是 private 的
    abstract class Shape {
    abstract private void draw();
    }
    // 编译出错
    Error:(4, 27) java: 非法的修饰符组合: abstract和private
  3. 抽象类中可以包含其他的非抽象方法, 也可以包含字段. 这个非抽象方法和普通方法的规则都是一样的, 可以被重写,
    也可以被子类直接调用
    abstract class Shape {
    abstract public void draw();
    void func() {
    System.out.println(“func”);
    }
    }
    class Rect extends Shape {

    }
    public class Test {
    public static void main(String[] args) {
    Shape shape = new Rect();
    shape.func();
    }
    }
    // 执行结果
    func
    抽象类的作用
    抽象类存在的最大意义就是为了被继承.
    抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法.
    使用抽象类相当于多了一重编译器的校验.

接口
接口是抽象类的更进一步. 抽象类中还可以包含非抽象方法和字段. 而接口中包含的方法都是抽象方法, 字段只能包含静态常量
语法规则:
1、使用 interface 定义一个接口
2、接口中的方法一定是抽象方法, 因此可以省略 abstract
3、接口中的方法一定是 public, 因此可以省略 public
4、Cycle 使用 implements 继承接口. 此时表达的含义不再是 “扩展”, 而是 “实现”
5、在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例.
6、接口不能单独被实例化.
7、接口中只能包含抽象方法. 对于字段来说, 接口中只能包含静态常量(final static).

实现多个接口
一个类继承一个父类, 同时实现多种接口.
时刻牢记多态的好处, 让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力.
接口使用实例:

刚才的例子比较抽象, 我们再来一个更能实际的例子.
给对象数组排序:
1、给定一个学生类,再给定一个学生对象数组, 对这个对象数组中的元素进行排序;
2、仔细思考, 不难发现, 和普通的整数不一样, 两个整数是可以直接比较的, 大小关系明确. 而两个学生对象的大小关系怎么确定? 需要我们额外指定.
3、让我们的 Student 类实现 Comparable 接口, 并实现其中的 compareTo 方法
4、在 sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.然后比较当前对象和参数对象的大小关系(按分数来算).
接口间的继承
接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字
Clonable 接口和深拷贝
Java 中内置了一些很有用的接口, Clonable 就是其中之一.
Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出CloneNotSupportedException 异常.

总结:
抽象类和接口核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法, 子类必须重写所有的抽象方法.
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_47631612/article/details/112725117