封装、继承

封装、继承

回顾

1 面向对象思想: 一种思维方式,着眼于找到一个具有特殊功能的具体个体,然后委托这个个体去做某件事情。

  面向过程思想:一种思维方式,着眼于解决问题的过程和步骤。

2 类的概念 : 一类具有相同属性和功能的实体的集合[群体]

3 对象:一个具体特殊功能的实体。

4 类和对象的关系:类是对象的抽象或模板,对象是类的具体或实例

5 定义类  

    public   class  Person{

        //成员变量  属性

        //方法

    }

6 创建对象 

    类名  对象名=new 类名();

    //使用对象的属性和方法

    对象名.属性名

    对象名.方法名(实参);

      对象的内存分配

      栈:空间比较小,存取速度快,特点:先进后出  jdk 1.5 256k  jdk1.5 1M

      堆:空间比较大,存取速度慢。

      方法区 (静态区,串池(常量池), 代码段)



7 构造方法:创建对象时调用的方法。

    public  类名(){

    }   

    默认构造方法

    带参构造方法 :初始化对象的属性

     构造方法重载 

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

    this.属性
        如果参数名和成员变量相同时,可以使用this.区分

    this.方法()

    this();//调用其他的构造方法
        this()只能用在构造方法中,必须是第一条语句
        this()只能调用一次

今天任务

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

教学目标

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 引用数据类型传递

数组、类、String(比较特殊特点:和基本类型一样)

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:

编写学生类:

    学号,姓名,年龄,地址

    显示信息方法

编写学生管理类

    输入学生信息(学生作为方法返回值)

    修改学生信息(学生作为参数传递)
1.3基本类型和引用类型作为方法的返回值

基本类型返回的实际数据

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

第二节:封装性

Java语言有三大特征:

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

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

封装成员变量两个步骤:

第一步: 添加private 修饰符

第二步: 添加get和set方法

1.2 private

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

1.3 get和set方法

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

语法:

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

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

public void setXxx(参数类型 参数){
      this.xxx = 参数;
}
package com.qf.day09_4;
/**
 * 人类
 *  属性: 姓名 年龄 性别
 *  方法: eat study
 *  
 *  封装:(1)把成员变量变成私有的  (2)  添加get和set方法
 * @author wgy
 *
 */
public class Person {
    private String name;
    private int age;
    private String sex;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name=name;
    }
    
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        if(age>100||age<1) {
            this.age=18;
        }else {
            this.age=age;
        }
    }
    
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        if(sex.equals("男")||sex.equals("女")) {
            this.sex=sex;
        }else {
            this.sex="男";
        }
    }
    
    
    
    public void eat() {
        System.out.println(name+"开始吃饭...");
    }
    public void study() {
        System.out.println(name+"开始努力学习...");
    }
    public void show() {
        System.out.println("姓名:"+name+" 年龄:"+age+" 性别:"+sex);
    }
}
1.4 类设计原则
  • 成员变量(属性)私有化(用private修饰),添加get和set方法
  • 公开方法(用public修饰)

第三节:static关键字

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

成员变量(1 静态成员变量(类变量、静态属性),2非静态成员变量(实例变量)),但是在某些情况下,成员变量特指实例变量。

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关键字修饰的动态代码块,在类加载时自动执行,并只执行一次。(记住)

第四节:继承性

4.1 继承的概念

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

4.2 继承的好处
  • 实现代码的重用和扩展

  • 模拟现实世界的关系

4.3 类的继承的使用

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

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

继承的类:子类,派生类

继承符合: 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:

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

Animal类

package com.qf.day09_2;
/**
 * 动物类 
 *  (名字、颜色、品种),打印方法
 * @author wgy
 *
 */
public class Animal {
    //昵称
    String name;
    //颜色
    String color;
    //品种
    String strain;
    
    //打印信息
    public void print() {
        System.out.println("动物信息: 昵称:"+name+" 颜色:"+color+" 品种:"+strain) ;
    }
}

Dog类

package com.qf.day09_2;
/**
 * 狗狗类
 * @author wgy
 *
 */
public class Dog extends Animal{
    //亲密度
    int love;
    

    
    public void lookHome() {
        System.out.println(name+" 正在给主人看家...........");
    }
    
}

Cat类

package com.qf.day09_2;
/**
 * 猫类
 * @author wgy
 *
 */
public class Cat extends Animal{
    //爱好
    String hobby;
    
    /**
     * 玩球
     * 
     */
    public void playBall() {
        System.out.println(name+"正在玩球..........");
    }
}
4.5 子类对象实例化过程
  • 1 先实例化父类对象
    • 默认调用父类默认构造方法
  • 2 再实例化子类对象
4.6 不能被子类继承的成员:

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

4.7 继承的特点:

1)单继承:一个子类只能有一个父类,一个父类可以有多个子类
2)传递性:继承具有传递性

第五节:super关键字

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

this 表示当前对象的引用。

this用法:

​ 用法1:调用本类的属性,可以解决成员变量名和局部变量名同名问题。

​ this.属性名

​ 用法2:调用本类的方法

​ this.方法名

​ 用法3 :调用本类中其他的构造方法。

​ this(参数);

​ 注意:1只能用在构造方法中,必须是第一条语句

​ 2只能调用一次

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 print() {
        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.print();
    }
}

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();
    }
}

this和super的区别:

​ (1) this表示当前对象的引用,super表示当前父类对象的引用

​ (2) this.属性可以调用当前对象的属性包括继承的属性,super.属性可以调用父类的属性

​ (3) this.方法() 可以调用当前对象的方法包括继承的方法,super.方法()可以调用父类的方法

​ (4) this(参数) 调用本类中其他的构造方法,super(参数) 调用父类的构造方法

​ (5) this(参数)和super(参数)只能用在构造方法中,必须是第一条语句,只能调用一次,不能同时使用。

第六节:包

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

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

  • 用package来声明包,package语句必须是java源文件中的第一条语句。(若无这条语句,则放置在无名包下)
  • 在package语句中,用"."来指明包(目录)的层次。包对应着文件系统的目录层次结构。
  • 一般使用公司或组织的域名的倒置+项目名或模块名来表示包名。
    • www.baidu.com 包名 com.baidu.oa
    • www.alibaba.com 包名 com.alibaba.pay
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;
    }
    //getter和setter省略
 } 
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
  • 局部变量不能访问权限修饰符。

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

方法重载(overload):

​ 1 同一个类中,方法名相同,参数列表不同(个数不同,类型不同,顺序不同)

​ 2 和返回值,访问修饰符无关。

8.1 方法重写
    在继承过程中,子类中从父类继承来的方法无法满足自己的需求时,可以在子类中对父类方法进行完善,这个完善过程叫做方法重写(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 10;
    }
}


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(参数);  调用父类的构造方法

    this和super的区别

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

    域名倒置+项目名

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

       导包

        import java.util.*;

7 访问权限修饰符

    public :公开的  

    protected:包含的

    [default]:默认的

    private:私有的 

    类可以用 public  或默认

    成员变量和方法  四个都可以用

8 方法重写:

    重写规则:

    1 在继承中,方法名、参数列表、返回值必须和父类的方法相同

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

默写

1 什么是类? 什么是对象? 类和对象的关系
2 this关键字的使用?

作业

​ 1 设计一个矩形类(Rectangle),有长,宽属性,计算周长功能,计算面积的功能

​ 2 设计一个四棱柱类(Column),有底面矩形、高属性,计算表面积,计算体积

面试题

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

猜你喜欢

转载自www.cnblogs.com/Zzzxb/p/11369111.html