面向对象编程

本文详细介绍了Java面向对象编程的各个方面,包括类的访问修饰符、如何导入类、封装、继承以及多态。重点讲解了继承的规则、super关键字的应用、多态的向上转型和方法重写。此外,还探讨了protected访问权限和final关键字的作用。

目录

一、类的访问修饰符

二、如何导入某个包中的某个类?(import 导入类)

1、import语句:

2、导入包中的若干类:

3、静态导入:

 4、常见的系统包

三、封装

四、继承

1、继承:

2.继承的规则

 3、protected访问权限

 4、继承的规则(产生子类对象之前,默认先产生一个父类对象)

5.super关键字

 6.final 关键字(终结器)

 7.类之间的组合关系(has a)

五、多态

1、多态性:

2、多态的向上转型(一定发生在有继承关系的类之间)

3.方法重写(override):

4、向下转型  (将父类引用强制转换为子类引用)(要发生向下转型,首先要发生向上转型)


一、类的访问修饰符

从小到大依次为:

private(私有,当前类的内部可见)  <  default(包访问权限,当前包的内部可见,不包含子包 ,同级目录下可见)< protected (继承访问权限 ,不同包的有继承关系的类之间可见) < public (当前项目可见)

java中的“包”就是操作系统的文件夹,声明一个包使用package关键字,若存在多个文件夹的嵌套,使用“.”分隔,如 package www.java.se

IDEA显示空包:

 类的全名称:包名.类名(包的存在就是为了解决类同名的问题)

二、如何导入某个包中的某个类?(import 导入类

1、import语句:

只能导入相关包中的某个具体的类

2、导入包中的若干类:

import java.包名称.*(一般不推荐,可能存在歧义)

如:import java.util.*    //将整个util包下的所有类按需加载,此时导入的还是类,而不是把整个util文件夹导入 

 当程序中用到了两个相同名称的类

(1)使用类的全名称

(2)明确指定导入的是哪个包下的哪个类

3、静态导入:

import static 可以导入包中的静态方法和静态属性(不推荐,还是使用类名.方法名称/属性名称 访问类中的静态域)

 

 4、常见的系统包

(1)java.lang :JDK的基础类,System,String,Object都在这个包下,JDK1.1后这个包下的所有类自动导入

(2)java.lang.reflect:反射开发包

(3)java.util :工具包(集合类都在这个包下,Arrays,LinkedList,HashMap)

(4)java.io :I/O开发包,文件的读取和写入

(5)java.net:网络编程开发包,Socket

(6)java.sql :数据库开发包

三、封装

 封装:保护性和易用性

封装有很多表现形式,private实现属性和方法的封装只是其中一种

private(私有的):被private 修饰的属性和方法,只在当前类可见,出了类的{ },对外就完全隐藏了,外部不知道有其存在。

//公共访问权限,主类
public class privateTest {
    public static void main(String[] args) {
        Bank bank = new Bank();
        bank.setPassword();
        System.out.println("修改后的密码为:");
        System.out.println(bank.getPassword());
        System.out.print("银行卡号为:");
        System.out.println(bank.getCardNum());
        System.out.print("银行卡余额为:");
        System.out.println(bank.getBalance());
    }
}
//缺省修饰符,包访问权限
class Bank{
    //私有属性,只在Bank这个类内部可见
    private int cardNum;//卡号,只可取
    private double balance;//余额,只可取
    private String password = "123456";//密码,既可取也可改
//要在类的外部去使用这些私有属性,需要使用类提供的getter()和setter()方法
    //alt + insert 快速生成getter()和setter()方法
    //shift+A全选
    //get + 属性名称 = 方法命名
    public int getCardNum() {
        return cardNum;
    }

    public double getBalance() {
        return balance;
    }

    public String getPassword() {
        return password;
    }
//设置新密码
    public void setPassword() {
        //验证旧密码(安全性)
        Scanner scan = new Scanner(System.in);
        int count = 0;
        while(true){
            System.out.println("请输入您的旧密码:");
            String oldPass = scan.nextLine();
            count ++;
            if (oldPass.equals(password)) {
                System.out.println("验证成功,请输入您的新密码:");
                String newPass = scan.nextLine();
                password = newPass;
                System.out.println("密码修改成功");
                break;
            }else{
                System.out.println("密码错误,请查证后再试!");
                if(count == 3){
                    System.out.println("验证次数过多,银行卡已锁定");
                    break;
                }
            }
        }
    }
}

 

四、继承

1、继承:

当类和类之间满足一个类 is a 另外一个类,一定存在继承关系。当一个类继承了另一个类,另一个类中所有的属性和方法子类就天然具备了。 Java中使用extends表示类的继承。

如:Bird is an Animal;

Dog is an Animal;

Bird、 Dog都是 Animal 的子类。

2.继承的规则

(1)要能使用继承,前提必须满足类之间的 is a 关系

Person extends Dog{} ×

Person is not a Dog

(2)一个子类只能使用extends继承一个父类(单继承)。

Java中不允许多重继承,extends 后面只能跟一个父类,但允许多层继承。

(3)子类会继承父类的所有属性和方法(类属性、类方法以及成员属性、成员方法)(显示继承(public属性和方法可以直接使用)和隐式继承(private 属性和方法,子类也继承这类属性和方法,但是无法直接使用))

public class Animal {
    public String name;
    //age这个属性只在当前类的内部可见,子类其实也继承了,但是没法直接使用
    private int age;

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void eat(String name, String food){
        this.name = name;
        System.out.println( name+"正在吃" +food);
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.eat("小王","蔬菜");
        Dog dog = new Dog();
        dog.setAge(10);
        System.out.println(dog.getAge());
        dog.eat("花花","狗粮");
    }
}

 3、protected访问权限

语义:作用域同包下(不包含子包)的类之间(不管有无继承关系)以及不同包的有继承关系的类之间可见(但出了这个类,在不同包的其他类中则不可见)【只在当前包和子类的内部可见】。

 

 4、继承的规则(产生子类对象之前,默认先产生一个父类对象)

5.super关键字

this关键字:表示当前对象的引用

(1)修饰属性,表示从当前类中找同名属性

 this关键字表示从当前类寻找同名属性,若不存在,继续向上寻找父类中是否存在同名属性。

public class Person {
    protected String name = "Person";
   
}
public class China extends Person {
    protected String name = "China";
    public void show(){
        System.out.println(name);//相当于this.name  默认在当前类中寻找同名属性
                                 //若没找到,才会向上寻找父类中的同名属性
    }

    public static void main(String[] args) {
        China china = new China();
        china.show();
    }
}

(2)修饰方法(普通方法和构造方法)

(3)表示当前对象的引用

super关键字

(1)修饰属性,表示直接从父类中寻找同名属性。先从直接父类中去寻找同名属性,若不存在再向上寻找(爷爷类)

public class Animal {
    protected String name = "Animal";
}
public class Person extends Animal {
    protected String name = "Person";
}

 若直接父类中没有同名属性,继续向上寻找。

不能使用super关键字直接调用父类private权限的属性

public class Animal {
    protected String name = "Animal";
}

public class Person extends Animal{
    private String name = "Person";
}

public class China extends Person{
   protected String name = "China";

   protected void print(){
       System.out.println(super.name);
   }

    public static void main(String[] args) {
        China china = new China();
        china.print();
    }
}

  

(2)修饰方法,表示直接从父类中去寻找方法

(2-1)修饰构造方法

super(父类构造方法的参数);

super();//直接父类的无参构造,可写可不写。若父类中不存在无参构造,则子类构造方法的首行必须使用super(有参构造)以显示调用。

若产生子类对象,默认先产生父类对象,若父类对象上还有基础,继续向上先产生祖类对象,最后产生子类对象。

public class Animal {
    protected String name = "Animal";
    public Animal(){
        System.out.println("Animal类的无参构造");
    }
}
public class Person extends Animal {
   protected String name = "Person";
   public Person(){
       System.out.println("Person类的无参构造");
   }
}

public class Person{
    protected String name = "Person";

    public Person(String name) {
        this.name = name;
        System.out.println("Person的有参构造");
    }
}


public class China extends Person{
   protected String name = "China";

   public China(){
       System.out.println("China的无参构造");
   }

   protected void print(){
       System.out.println(super.name);
   }

    public static void main(String[] args) {
        China china = new China();
    }
}

public class Person  {
   protected String name ;
   public Person(String name){
       this.name =name;
       System.out.println("Person类的有参构造");
   }
}


public class China extends Person{
   protected String name = "China";

   public China(){
       super("小羊");
       System.out.println("China的无参构造");
   }

   protected void print(){
       System.out.println(super.name);
   }

    public static void main(String[] args) {
        China china = new China();
    }
}

 注意:在一个构造方法中,无法同时显式使用 this()和super(),因为这两个都要放在首行。

 (2-2)修饰普通方法(直接从父类中寻找同名方法,和super修饰属性相同)

public class China extends Person {
    protected String name = "China";
    public China(){
        super("小王");
        System.out.println("China类的无参构造");
    }

    public void test(){
        show();
    }

   public void show() {
       System.out.println("China类的show方法");
    }
    
    public static void main(String[] args) {
        China china = new China();
        china.test();
    }
}

 

(3)super 关键字不表示父类对象的引用 

 6.final 关键字(终结器)

 (1)修饰属性表示属性值不能变,常量

(2)修饰类,表示这个类无法被继承

 7.类之间的组合关系(has a)

class School {

Student  student ;

Teacher teacher;

}

School has a student;

School has a teacher;

五、多态

1、多态性:

同一个引用调用同一个方法名,根据引用指向的不同的对象可以表现出不同的行为、特性

2、多态的向上转型(一定发生在有继承关系的类之间)

意义:参数统一化,降低使用者的使用难度。

其中子类对象不一定是直接子类,也可以是孙子类...只要是这个父类分支下的都可

有向上转型后,最顶端的父类引用就可以指代所有的子类对象。当最顶端的父类有一个新的子类时,便很容易扩展。

3.方法重写(override):

发生在有继承关系的类之间,子类定义了和父类除了权限不同,其他全都相同的方法,这样的一组方法称为方法重写。方法重写的返回值必须严格相同,向上转型除外。

判断调用的是谁的方法:不用看前半部分,看当前是通过哪个类new 的对象,若该类重写了该方法,则调用的一定是重写后的方法。

public class Animal {
public void eat(){
    System.out.println("Animal类的eat方法");
}
}

public class Bird extends Animal{
    public void eat(){
        System.out.println("Bird类的eat方法");
    }
}


public class Duck extends Bird {
    public void eat(){
        System.out.println("Duck类的eat方法");
    }
}


public class Test {
    public static void test(Animal animal){
        animal.eat();
    }

    public static void main(String[] args) {
         public static void main(String[] args) {
      test(new Animal());
      test(new Bird());
      test(new Duck());
    }
    }
}

 若子类没有重写方法,则向上搜索碰到第一个父类重写的方法就调用这个“最接近”的重写方法。

 当发生重写时,子类权限 >= 父类权限才可以重写(private 权限不包含在内)

 问:能否重写static方法?

不能。多态的本质就是调用了不同的子类对象,这些子类对象所属的类覆写相应的方法才能表现出不同的行为,static 方法和对象无关!方法重写只发生在普通方法中。

区别方法重载(overload)方法重写(override)
1范围一个类有继承关系的类之间
2概念方法名称相同、参数的类型及个数不同方法名称、参数的类型及个数、返回值类型完全相同(或者向上转型的返回值类型)
3限制没有权限要求被覆写的方法的访问控制权限 >= 父类方法的权限
4static方法没要求不能重写static方法

向上转型发生的3种时机:

(1)方法传参

(2)引用赋值时

(3)方法返回值

 

4、向下转型  (将父类引用强制转换为子类引用)(要发生向下转型,首先要发生向上转型)

4.1向上转型语法

类名称  引用名称 = new  类实例();

引用名称 . 方法名称

能通过“.”访问的方法由类名称说了算,能访问的这些方法必须都在类中定义过,编译器会先在类中查找是否包含在指定方法。至于方法最终表现出的是哪个类的样子,由实例所在的方法说了算。

Animal  animal  =  new  Dog();

animal. 方法名称(); 

// 这个方法是否能调用,看Animal

// 表现出来的行为由具体new的子类说了算

 

4.2 向下转型的语法

子类名称  子类引用 = (子类名称)父类引用

Animai  animal = new Dog(); //向上转型

Dog dog  = (Dog) animal;  //向下转型

何时使用向下转型?已知只有一个父类引用,但是要使用子类拓展的方法,此时就要把这个父类引用还原为子类引用(只有一个对象,并没有创建新的对象)

 4.3要发生向下转型,首先要发生向上转型,毫不相干的两个类之间无法强转

4.4当发生向下转型时会有风险,类型转换异常,使用 instanceof关键字

引用名称  instanceof  类  ——>返回布尔值,表示该引用指向的本质是不是该类的对象 

 使用instanceof关键字的返回值搭配分支语句进行类型转换


    public static void main(String[] args) {

        Animal animal1 = new Animal();
        Animal animal2 = new Dog();
        if(animal1 instanceof Dog){
            Dog dog = (Dog)animal1;
            System.out.println(animal1 +"转型成功");
        }else {
            System.out.println(animal1 +"不是指向Dog()类型的引用");
        }
        if(animal2 instanceof Dog){
            Dog dog = (Dog)animal2;
            System.out.println(animal2 +"转型成功");
        }else {
            System.out.println(animal2 +"不是指向Dog()类型的引用");
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值