Java学习笔记——封装、继承

封装、继承

1. 方法的参数传递返回值
2. 封装
3. static
4. 继承
5. super
6. 包、访问权限修饰符
7. 方法重写

第一节:方法的参数传递、返回值

Java语言在给被调用方法的参数赋值时,采用传值的方式:

  • 基本类型数据传递的是该数据的值本身。
  • 引用类型数据传递的也是这个变量的值本身,即对象的地址(引用),而非对象本身。

1.1基本数据类型传递

public class PassValue{
    public void change(int x){
        x = 100;
        System.out.println(“方法中x==” + x);
    }
}
public class Test{
     public static void main(String[] args){
        PassValue pv = new PassValue();
        int x = 5;
        System.out.println(“方法调用之前x==” + x);
        pv.change(x);
        System.out.println(“方法调用之后x==” + x);
    }
}

1.2 引用数据类型传递

public class PassValue2{
    int x ;
    public void change(PassValue2 obj){
        obj.x = 100;
        System.out.println(“方法中obj.x==” + obj.x);
    }
}

public class Test{
   public static void main(String[] args){
        PassValue2 p = new PassValue2();
        p.x = 5;
        System.out.println(“方法调用之前p.x==” + p.x);
        p.change(p);
        System.out.println(“方法调用之后p.x==” + p.x);
    }
}

1.3基本类型和引用类型作为方法的返回值

基本类型返回的实际数据

引用类型返回的是对象的地址

上机练习1:

编写学生类:

    学号,姓名,年龄,地址

    显示信息方法

编写学生管理类

    输入学生信息(返回值类型学生对象)

    修改学生信息(学生作为参数传递)

第二节:封装性

Java语言有三大特征:

  • 封装:对外部不可见,隐藏对象的属性和实现细节。
  • 继承:一个类继承另一个类的成员。
  • 多态:每个对象表现的多样性。

1.1 封装的概念

什么是封装:在类中,对于不想被类外直接访问的成员变量,进行私有化,同时对外提供一个公有的方法为了访问私有的成员。

封装成员变量两个步骤:

1 添加private

2 添加get和set方法

1.2 private

使用private访问权限实现成员变量的私有化,private修饰的成员变量就是私有成员变量,只能在类内部直接访问,类外不能直接访问

1.3 get和set方法

get方法表示访问私有属性的方法:

语法:

public 属性类型 getXxx(){
    return 属性;
}

set方法表示修改私有属性的值的方法:

public void setXxx(参数类型 参数){
    this.xxx = 参数;
}

1.4类设计原则

  • 成员变量(属性)私有化(用private修饰),添加get和set方法
  • 公开方法(用public修饰)

第三节:static关键字

static关键字只能修饰类成员,修饰成员变量和方法

2.1 静态属性

所有本类对象所共有且相同的一个属性,是类的公用变量,不会随着对象的改变而改变的属性。例如:圆周率。静态属性先于对象,不依赖于对象,可以直接通过类名直接访问(类名.属性名)。

public class Person{
    String name;
    int age;
    //人口总数
    static int totalCount = 1300000000;
}
public class DemoPerson{
    public static void main(String[]args){
        System.out.println(Person.totalCount);//Person类中的totalCount属性是一个静态属性,可以直接通过类名访问
    }
}

2.2 静态方法

所有本类对象所共有且相同的一个公共方法,属于类方法,先于对象的方法,不依赖于对象,可以直接通过类名直接调用(类名.方法名())。

public class Person{
    static int totalCount;
    public static void calcTotalCount(){
        System.out.println("统计人口方法");
        totalCount=1350000000;
    }
}
public class DemoPerson{
    public static void main(String[]args){
        Person.calcTotalCount();
    }
}

使用静态属性和方法的原则:

1如果这个变量或方法,不属于每个对象,属于整个类,就用静态

    2如果这个对象只有一个,那么类中的属性和方法都用静态的,一般工具类中的方法静态的。  Arrays.方法名()

使用注意事项:

1 静态方法中可以直接访问静态变量,不能直接访问非静态变量。

2 非静态方法中可以直接访问静态变量和静态方法。

    3 静态变量存在方法区中静态域中

2.3 代码块

代码块分为:局部代码块,动态代码块,静态代码块

局部代码块:声明在方法中的代码块,执行时机与声明位置相关。(了解) 提前释放变量

动态代码块:又称构造代码块或实例代码块,声明在类体中的代码块,创建对象时自动执行一次,每创建一个对象就执行一次动态代码块。初始化工作。(使用不多)

静态代码块:使用static关键字修饰的动态代码块,在类加载时自动执行,并只执行一次。(记住)

package com.qf.day05_3;
/**
 * 代码块
 * 1 局部代码块(了解)方法内部
 * 2 动态代码块(了解)方法外部
 * 3 静态代码块 (重点)
 * @author wgy
 *
 */
public class Demo1 {


    public static void main(String[] args) {
        int i=10;
        System.out.println(i);
        //1局部代码块:提前释放局部变量,控制变量的作用域
        {
            int num=20;
            System.out.println(num);
        }
//      System.out.println(i);
//      System.out.println(num);


        Animal wangcai=new Animal();
        Animal afu=new Animal();

    }
}

package com.qf.day05_3;

public class Animal {
    String nickname;
    String color;
    int age;

    //动态代码块(实例代码块):作用:初始化对象属性
    //每创建一个对象都执行一次
    {
        System.out.println("动态代码块执行了...");
        nickname="xxx";
        color="yellow";
        age=3;
    }

    //静态代码块:作用:初始化静态属性
    //类加载的时候,只执行一次。
    static {
        System.out.println("静态代码块执行了...");
    }

    public Animal() {
        System.out.println("无参构造执行了...");
    }

    public void show() {
        System.out.println("昵称:"+nickname+" 颜色:"+color+" 年龄:"+age);
    }
}

第四节:继承

4.1 继承的概念

在原有类的基础上,产生一个新的类,在新的类中可以访问原有类中的非私有成员,并且可以添加一些自己独有的成员,这个过程叫做继承,简单理解一个类继承另外一个类。

4.2继承的好处

  • 实现代码的重用和扩展
  • 模拟现实世界的关系

4.3 类的继承的使用

1 使用extends关键实现两个类的继承关系

被继承的类:父类,根类,超类,基类

继承的类:子类,派生类

2 继承关系: is a 关系

4.4 语法:

public class FatherClass{
    //属性
    //方法
}
public class ChildClass extends FatherClass {
    //属性
    //方法
}

上机练习1

编写Person类:

    属性有:姓名、年龄,出生日期

    方法有:showInfo();

编写Student类:

    属性有:姓名、年龄,出生日期、学校

    方法有:showInfo();

            study();

使用继承优化Student类。

public class Person {
    String name;
    int age;
    String birthday;

    public void showInfo() {
        System.out.println("姓名:"+name+" 年龄:"+age+" 出生日期:"+birthday);
    }

}

public class Student extends Person{

    String school;


    public void study() {
        System.out.println(name+"好好学习天天向上");
    }
}

上机练习2:

编写动物类 (名字、颜色、品种),打印方法,编写狗狗类(亲密度)和猫类(爱好)继承动物类,狗狗类和猫类都有打印信息的功能,狗狗有看家方法,猫类有玩方法。

4.5 子类对象实例化过程

  • 1 先实例化父类对象
    • 默认调用父类默认构造方法
  • 2 再实例化子类对象

4.6 不能被子类继承的成员:

1)私有成员:私有成员不能被子类继承

2)构造方法:父类中的构造方法不能被子类继承,但是会在子类的构造方法中调用(子类的构造方法中默认第一条语句是调用父类的默认构造方法)

4.7 继承的特点:

1)单继承(单根性):一个子类只能有一个父类,一个父类可以有多个子类

2)继承具有传递性:一个子类可以继承父类的父类的成员。

第五节:super关键字

5.1 super关键字:用法和this类似

5.2 super的概念

super表示父类的引用

5.3 super的使用规则

1)super.属性:表示访问父类中的属性,当子类中定义了与父类同名的属性时,若想在子类中访问父类的同名属性,需要使用super.属性访问

2)super.方法:表示调用父类中的方法,在子类中需要调用父类中没有被重写的方法时,需要使用super.方法调用

3)super():表示调用父类的构造方法,注意:super()必须是子类构造方法中第一条语句

子类中构造方法默认第一条语句会调用父类的无参数构造方法super(),也可以手动调用父类中带参数的构造方法

5.4 练习

public class Animal {
    //属性
    String nickname;
    String color;
    String strain;

    //默认构造方法
    public Animal() {
        System.out.println("父类Animal的构造方法执行了..........");
    }

    //带参构造方法()
    public Animal(String nickname,String color,String strain) {
        this.nickname=nickname;
        this.color=color;
        this.strain=strain;
    }


    //打印方法
    public void printInfo() {
        System.out.println("本动物 昵称:"+nickname+" 颜色:"+color+" 品种:"+strain);
    }
}

public class Dog extends Animal{


    int love;
    //默认构造方法
    public Dog() {
        super();//调用父类的默认构造方法
        System.out.println("Dog子类的构造方法执行了");
    }
    //带参构造方法
    public Dog(String nickname,String color,String strain,int love) {
        super(nickname, color, strain);//调用父类的带参构造
        this.love=love;
    }


    public void lookHome() {
        System.out.println(nickname+"正在给主人看家....");
        System.out.println("昵称:"+super.nickname);
        System.out.println("颜色:"+super.color);
        System.out.println("品种:"+super.strain);
        System.out.println("亲密度:"+this.love);
        super.printInfo();
    }
}

public class Test {
    public static void main(String[] args) {
        Dog afu=new Dog();
        afu.nickname="阿福";
        afu.color="黑色";
        afu.strain="哈士奇";
        afu.love=100;
        afu.lookHome();
        System.out.println("----------------------------------------");
        //调用Dog的带参构造
        Dog xiaohei=new Dog("小黑", "白色", "泰迪", 100);
        xiaohei.lookHome();
    }
}

第六节:包

为了便于管理大型软件系统中数目众多的类,解决类命名冲突的问题,Java引入了包(package)。

在使用许多类时,类和方法的名称很难决定。有时需要使用与其他类相同的名称。包基本上隐藏了类并避免了名称上的冲突。

  • 用package来声明包,package语句必须是java源文件中的第一条语句。(若无这条语句,则放置在无名包下)
  • 在package语句中,用”.”来指明包(目录)的层次。包对应着文件系统的目录层次结构。
  • 一般使用公司或组织的域名的倒置+项目名或模块名来表示包名。

6.1 创建包

package com.qf.test;

public class Employee {
    private String name;        //姓名
    private int age;                //年龄
    private double salary;     //薪水

    public Employee(){

    }
    public Employee(String name, int age, double salary){    //构造方法
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
 } 

6.2 导入包

为使用定义在不同包中的Java类,需要import语句来引入所需要的类。

语法格式:

import package1[.package2…].类名

import com.qf.test.Employee;

public class PackageDemo {  
    public static void main(String args[]){
        Employee employee = new Employee();
    }
}

注意:

要导入某个包中的所有类可以用:包名.*

例如:import  java.util.*;

在同一包中的类可以直接互相引用,无需import语句。 

第七节:访问权限

            本类      同包中类或同包子类   不同包子类   不同包类

public v v v v
protected v v v x
默认[default] v v x x
private v x x x

package a;
public class Person{
    public String name;
    protected int age;
    char sex;
    private double sal;
    public Person(){}
    public Person(String name, int age, char sex, double sal){
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.sal = sal;
    }
    public static void main(String[]args){
        Person p = new Person("张三", 12, 'm', 5000);
        System.out.println(p.name);
        System.out.println(p.age);
        System.out.println(p.sex);
        System.out.println(p.sal);
    }
}

package a;
public class Student extends Person{
    public static void main(String[]args){
        Person p = new Person("张三", 12, 'm', 5000);
        System.out.println(p.name);
        System.out.println(p.age);
        System.out.println(p.sex);
        //System.out.println(p.sal);//同包子类中无法访问父类中私有成员
    }
}

package a;
public class Demo{
    public static void main(String[]args){
        Person p = new Person("张三", 12, 'm', 5000);
        System.out.println(p.name);
        System.out.println(p.age);
        System.out.println(p.sex);
        //System.out.println(p.sal);//同包类中无法访问父类中私有成员
    }
}

package b;
public class Student extends Person{
    public static void main(String[]args){
        Person p = new Person("张三", 12, 'm', 5000);
        System.out.println(p.name);
        System.out.println(p.age);
        //System.out.println(p.sex);//不同包中子类中无法访问默认权限成员
        //System.out.println(p.sal);
    }
}

package b;
public class Demo{
    public static void main(String[]args){
        Person p = new Person("张三", 12, 'm', 5000);
        System.out.println(p.name);
        //System.out.println(p.age);//不同包中不能访问受保护属性
        //System.out.println(p.sex);
        //System.out.println(p.sal);//不同包类中无法访问父类中私有成员
    }
}

使用原则:

  • 修饰类时:只能public 或 默认的
  • 修饰成员变量和方法:可以使用public 、默认、protected 、private
  • 局部变量不能访问权限修饰符。

第八节:方法重写(覆盖)

8.1 什么是方法重写:

在继承过程中,子类中从父类继承来的方法无法满足自己的需求时,可以在子类中对父类方法进行完善,这个完善过程叫做方法重写,方法的重写相当于在子类中覆盖父类中的方法。

overload:重载

override:重写

案例:

public class Animal {
    //属性
    String nickname;
    String color;
    String strain;

    //默认构造方法
    public Animal() {
        System.out.println("父类Animal的构造方法执行了..........");
    }

    //带参构造方法()
    public Animal(String nickname,String color,String strain) {
        this.nickname=nickname;
        this.color=color;
        this.strain=strain;
    }


    //打印方法
    protected Object printInfo() {
        System.out.println("本动物 昵称:"+nickname+" 颜色:"+color+" 品种:"+strain);
        return null;
    }
}


public class Dog extends Animal{


    int love;
    //默认构造方法
    public Dog() {
        super();//调用父类的默认构造方法
        System.out.println("Dog子类的构造方法执行了");
    }
    //带参构造方法
    public Dog(String nickname,String color,String strain,int love) {
        super(nickname, color, strain);//调用父类的带参构造
        this.love=love;
    }

    /**
     * 看家
     */
    public void lookHome() {
        System.out.println(nickname+"正在给主人看家....");
    }
    /**
     * 重写 :覆盖
     * 1 方法名相同
     * 2 方法参数  返回值类型必须相同
     * 3 访问修饰符不能比父类严格
     * 
     * java特殊 1.7  返回值 可以和父类兼容就可以,必须是引用类型
     */

    public String printInfo() {
        System.out.println("狗狗信息:昵称:"+super.nickname+" 颜色:"+super.color+" 品种:"+super.strain+" 亲密度:"+this.love);
        return "haha";
    }
}

8.2 方法重写的要求

访问权限 返回值 方法名(参数列表)

 * 1 方法名、方法参数、返回值类型必须相同
 * 2 访问修饰符不能比父类严格
 * 
 * java特殊 1.7  返回值可以和父类兼容就可以,必须是引用类型

8.3 方法的重写和方法的重载的区别

方法的重载:Overload,在同一个类中,方法名相同,参数类别不同,互为重载方法。

方法的重写:Override,在继承过程中,在子类中重写父类中继承来的方法,方法名相同,参数列表、返回值必须相同,访问权限不能比父类严格。

8.4 有关方法重写之后的调用:

只要在子类中重写了父类的方法,通过子类对象调用一定子类重写的方法。

总结:

1 方法传参 返回值

方法传参采用传值 :  基本类型传递的数据本身,引用类型传递的是地址

    返回值:基本类型返回数据本身,引用类型返回地址。

2 封装 :隐藏类的实现细节,保证程序安全。

2个步骤

第一步:私有化成员变量

第二步:添加get和set方法

3 static关键字

静态:

成员变量或方法属于所有对象共有的,不属于每个对象,使用静态。

4 继承: 在原有类的基础上,产生一个新的类,在新的类中可以访问原有类中的非私有成员,并且可以添加一些自己独有的成员,这个过程叫做继承,简单理解一个类继承另外一个类。

关键字 extends

集合符合 is a 关系

继承特点:1 单继承

    2 继承具有传递性

5 super关键字 :表示父类的引用

super.属性  

super.方法

super(); 

6 包: 管理类的,解决类的命名冲突问题。

域名倒置+项目名

package  com.qf.day09;   必须是第一句

   导包

    import java.util.*;

7 访问权限修饰符

public :公开的  

protected:包含的

[default]:默认的

private:私有的 

8 方法重写:

重写规则:

1 在继承中,方法名相同

2 参数列表 返回值相同

3 访问权限不能比父类更严格

面试题

方法重载与方法重写的区别

你可能感兴趣的:(Java基础)