您的位置:首页 > 编程语言 > Java开发

Java 基础 封装继承

2019-08-02 21:46 78 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/weixin_45472939/article/details/98242731

Java语言有三大特征:

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

1.1 封装的概念

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

封装成员变量两个步骤:

a. 添加private 修饰符

b. 添加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修饰)

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

3:继承

3.1 继承的概念

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

3.2继承的好处

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

3.3 类的继承的使用

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

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

继承的类:子类,派生类

继承符合 is a 关系

3.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+"好好学习天天向上");
}
}

3.5 子类对象实例化过程

  • 1 先实例化父类对象 默认调用父类默认构造方法
  • 2 再实例化子类对象
  • 3.6 不能被子类继承的成员:

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

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

    3.7 继承的特点:

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

    2)继承具有传递性

    4:super关键字

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

    this 表示当前类的对象

    this用法:

    1 调用本类的属性和方法,可以解决成员变量名和局部变量名同名问题。
    
    2 调用本类中其他的构造方法。
    
    注意:如果调用其他构造方法,只能第一条语句

    4.2 super的概念

    super表示父类对象

    4.3 super的使用规则

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

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

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

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

    练习

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

    拓展:

    1:方法重写(覆盖)

    方法重载(overload):

    1 同一个类中,方法名相同,参数列表不同(个数不同,类型不同,顺序不同)
    
    2 和返回值,访问修饰符无关。

    1.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";
    }
    }

    1.2 方法重写的要求

    访问权限 其他修饰符 返回值 方法名(参数列表)

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

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

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

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

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

    2:构造方法的定义

    2.1 构造方法的定义

    构造方法也叫构造器,是指当实例化一个对象(创建一个对象)的时候,第一个被调用的方法
    
    语法:
    
    访问权限修饰符 类名(参数列表) {
    //方法体
    }
    
    普通方法:
    
    访问权限修饰符 其他的修饰符 返回值类型 方法名(参数列表) {
    
    }
    
    注意:a.构造方法没有返回值类型,构造方法是在实例化对象的过程中自动调用的
    
    b.如果不写构造方法,系统会默认为我们提供一个无参的构造方法,如果添加了构造方法,系统不再提供默认的构造方法。

    2.2 构造方法的调用

    //演示构造方法的使用
    public class Test
    {
    public static void main(String[] args)
    {
    //创建动物
    Animal dog=new Animal();
    //使用属性
    dog.color="黄色";
    dog.nickname="旺财";
    dog.age=3;
    //使用方法
    dog.eat();
    }
    }
    
    public class Animal {
    //颜色
    String color;
    //昵称
    String nickname;
    //年龄
    int age;
    //默认构造方法
    public Animal() {
    
    }
    
    //吃
    public void eat() {
    System.out.println(nickname+"大口大口吃东西");
    }
    }

    2.3 构造方法和普通方法的区别

    a.构造方法是在创建对象的过程中自动调用的,普通方法只能手动进行调用
    
    b.构造方法没有返回值类型【注意区别返回值void】,普通方法的返回值类型要么是确定的类型,要么为void
    
    c.系统会默认为我们提供一个无参的构造方法,普通方法只能手动添加
    
    d.构造方法的方法名称必须和对应的类名保持一致
    
    e.构造方法在创建对象的过程中就会执行,而且每个对象只执行一次,对于普通方法而言,只有在需要使用的时候才被执行,并且一个对象可以调用多次

    2.4 构造方法重载

    方法重载:同一个类中,方法名相同,参数类别不同
    
    参数列表不同:个数不同,类型不同,顺序不同
    
    和返回值修饰符无关
    
    默认构造方法:只能创建对象,不能做任何初始化操作,如果实现创建对象时初始化属性,需要添加带参的构造方法,初始化对象的属性。如果一个类中有多个构造方法,这就是构造方法重载。
    
    //演示构造方法的重载
    //测试类
    public class Test
    {
    public static void main(String[] args)
    {
    //直接赋值
    /*
    Dog maomao = new Dog();
    maomao.name = "毛毛";
    maomao.age = 3;
    
    maomao.lookHome();
    */
    
    //通过构造方法赋值
    Dog dahuang = new Dog("大黄",5);
    dahuang.lookHome();
    }
    }
    
    //实体类
    public class Dog
    {
    //成员变量
    String name;
    int age;
    
    //构造方法
    public Dog() {}
    //有参的构造方法,参数一般设置为和成员变量有关的参数
    public Dog(String n,int a) {
    //给成员变量赋值
    name = n;
    age = a;
    }
    /*
    public Dog(String n) {
    name = n;
    }
    */
    
    //成员方法
    public void lookHome() {
    System.out.println(name + "看家");
    }
    }

    2.5 练习

    //测试类
    public class Test
    {
    public static void main(String[] args)
    {
    //场景:富二代王思聪开着新买的白色宝马在马路上奔跑,很自豪的向他的新女友炫耀
    /*
    富二代类
    特征:姓名  有钱
    行为:开车,炫耀
    
    汽车类
    特征:颜色,品牌
    行为:奔跑
    
    女友类
    特征:姓名
    */
    //1.创建一个富二代的对象
    RichMan wang = new RichMan("王思聪",true);
    
    wang.drive();
    wang.show();
    }
    }
    
    /*
    富二代类
    特征:姓名  有钱
    行为:开车,炫耀车
    */
    public class RichMan
    {
    //成员变量
    String name;
    boolean hasMuchMoney;
    
    //默认构造方法
    public RichMan() {
    
    }
    //带参构造方法
    public RichMan(String n,boolean is) {
    name = n;
    hasMuchMoney = is;
    }
    
    //成员方法
    public void drive() {
    Car c=new Car();
    c.brand="宝马";
    System.out.println(name + "开着豪车" + c.brand);
    }
    //展示
    public void show() {
    Car c=new Car();
    c.brand="宝马";
    GirlFriend gf=new GirlFriend();
    gf.name="凤姐";
    System.out.println(name + "向" + gf.name + "炫耀豪车" + c.brand);
    }
    }
    
    /*
    汽车类
    特征:颜色,品牌
    行为:奔跑
    */
    public class Car
    {
    //成员变量
    String color;
    String brand;
    
    //构造方法
    public Car() {}
    public Car(String c,String b) {
    color = c;
    brand = b;
    }
    
    //成员方法
    public void run() {
    System.out.println("一辆" + color + "的" + brand + "在奔跑");
    }
    }
    
    /*
    女友类
    特征:姓名
    */
    public class GirlFriend
    {
    //成员变量
    String name;
    
    //构造方法
    public GirlFriend(){}
    public GirlFriend(String n) {
    name = n;
    }
    }

    3:this关键字

    this:表示当前对象的引用。

    3.1 this.属性

    访问本类的成员属性

    作用:为了区分成员变量和形参变量名一样的情况

    成员变量默认值:

    引用类型:null

    基本类型:byte short int :0

    long : 0L
    
    float: 0.0f
    
    double:0.0
    
    char :0
    
    boolean:false

    3.2 this.方法

    访问本类的成员方法

    3.3 练习

    //演示this的使用
    public class Test
    {
    public static void main(String[] args)
    {
    //
    Cat maomao = new Cat("毛毛",10);
    maomao.show1();
    
    }
    }
    
    public class Cat
    {
    String name;//昵称
    int age;//年龄
    String color;//颜色
    
    //3.this()
    public Cat() {
    System.out.println("无参的构造方法被调用");
    }
    //1.this.属性
    public Cat(String name,int age,String color) {
    this.color = color;
    this.name=name;
    this.age=age;
    System.out.println("带参2构造方法被调用");
    }
    
    //2.this.方法
    //普通方法
    public void show1() {
    //在本类中调用方法时,this可以省略
    this.show2();
    }
    
    public void show2() {
    }
    }

    3.4 this()(了解)

    访问本类中的其他构造方法
    
    注意:
    
    a.必须出现在构造方法中
    
    b.访问的是除了当前构造方法之外的其他构造方法
    
    c.具体访问的是哪个构造方法,取决于所传的参数
    
    d.只能书写在构造方法的第一条语句
    
    e.this()在同一个构造方法中只能出现一次
    
    public class Test
    {
    public static void main(String[] args)
    {
    System.out.println("Hello World!");
    }
    }
    public class Dog
    {
    String name;
    int age;
    int num;
    String hobby;
    
    //提高代码的可读性,可维护性
    //构造方法
    public Dog() {
    }
    public Dog(String name) {
    this.name = name;
    }
    public Dog(int age) {
    this.age = age;
    }
    
    public Dog(String name,int age) {
    this.name = name;
    this.age = age;
    }
    public Dog(String name,int age,int num,String hobby) {
    this(name,age);
    this.num= num;
    this.hobby = hobby;
    }
    }
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: