小白学习Java第四天,封装、继承、多态

1 篇文章 0 订阅
1 篇文章 0 订阅

本博客主要对在JAVA学习过程的重点及难点信息进行总结,可能存在知识点不全的现象,如:Scanner类、String类、Math类等。如果大家有需要可以私聊博主,会发给大家详细的学习讲义,希望共同进步。

一、封装

1、Java语言是一种面向对象的程序设计语言,而面向对象思想是一种程序设计思想,我们在面向对象思想的指引下,使用Java语言去设计、开发计算机程序。 这里的对象泛指现实中一切事物,每种事物都具备自己的属性和行为。面 向对象思想就是在计算机程序设计过程中,参照现实中事物,将事物的属性特征、行为特征抽象出来,描述成计算 机事件的设计思想。它区别于面向过程思想,强调的是通过调用对象的行为来实现功能,而不是自己一步一步的去操作实现。
:是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该 类事物。
属性:就是该事物的状态信息。
行为:就是该事物能够做什么。
类的定义格式:

public class ClassName { 
	//成员变量 
	//成员方法
 }

2、面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改。封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。要访问该类的数据,必须通过指定的 方式。适当的封装可以让代码更容易理解与维护,也加强了代码的安全性
封装的步骤:
1)使用 private 关键字来修饰成员变量。
2)对需要访问的成员变量,提供对应的一对 getXxx 方法 、 setXxx 方法。
其中getXxx 方法:无参数,有返回值,可以理解为往外放,需要返回值。setXxx 方法:有参数,无返回值,可以理解为往里放,不用返回值。

public class Student { 
	private String name; 
	private int age; 
	public void setName(String n) { 
		name = n; 
	}
	public String getName() { 
		return name; 
	}
	public void setAge(int a) { 
		age = a; 
	}
	public int getAge() { 
		return age;
	} 
}

当一个对象被创建时候,构造方法用来初始化该对象,给对象的成员变量赋初始值。
构造方法的定义格式:

修饰符 构造方法名(参数列表){ 
	// 方法体 
}

构造方法可分为两种:空参构造和有参构造,空参构造是系统自带的,括号里没有参数,有参构造括号里有参数。构造方法的写法上,方法名与它所在的类名相同。它没有返回值,所以不需要返回值类型,甚至不需要void。

二、继承

继承:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接 访问父类中的非私有的属性和行为。
好处:
1) 提高代码的复用性
2)类与类之间产生了关系,是多态的前提
子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用 super 关键字,修饰 父类成员变量,类似于之前学过的 this 。
如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对 应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。
如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。
方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。
重写的应用:子类可以根据需要,定义特定于自己的行为。既沿袭了父类的功能名称,又根据子类的需要重新实现父类方法,从 而进行扩展增强。比如新的手机增加来电显示头像的功能。
继承后的特点——构造方法
1)构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
2) 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构 造方法中默认有一个 super() ,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。代码如下:

class Fu { 
	private int n; 
	Fu(){ 
		System.out.println("Fu()"); 
	} 
}
class Zi extends Fu { 
	Zi(){
	 // super(),调用父类构造方法 
	 super();
	 System.out.println("Zi()"); 
	 } 
}public class Demo{ 
public static void main (String args[]){ 
Zi zi = new Zi(); 
	} 
}
输出结果: 
Fu() 
Zi()

继承实例,发红包:
群主发普通红包。某群有多名成员,群主给成员发普通红包。普通红包的规则:
1)群主的一笔金额,从群主余额中扣除,平均分成n等份,让成员领取。
2)成员领取红包后,保存到成员余额中。
案例分析:
在这里插入图片描述
案例代码:

package com.cp.demo.Demo1;

import java.util.ArrayList;
import java.util.Random;

public class Demo_HongBao {
    public static void main(String[] args) {
        Manager manager=new Manager("群主",100);

        Member one=new Member("成员A",0);
        Member two=new Member("成员A",0);
        Member three=new Member("成员A",0);

        manager.show();
        one.show();
        two.show();
        three.show();

        System.out.println("-----------");

        //群主发了20元三个红包
        ArrayList<Integer> redList =manager.send(20,3);
        //三个普通成员收红包
        one.receive(redList);
        two.receive(redList);
        three.receive(redList);

        manager.show();
        one.show();
        two.show();
        three.show();
    }
}
class User{
    private  String name;//姓名
    private  int money;//余额,当前账户用于的钱

    public User() {
    }

    public User(String name, int money) {
        this.name = name;
        this.money = money;
    }

    //显示当前用户有多少钱
    public  void show(){
        System.out.println("我叫"+name+",我有"+money+"元钱");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}

//群主的类
class Manager extends  User{
    public Manager(){
    }

    public Manager(String name, int money) {
        super(name, money);
    }
    public ArrayList<Integer> send(int totalMoney,int count){
        //首先需要一个集合,来存储若干个红包的金额
        ArrayList<Integer> redList=new ArrayList<>();

        //首先看一下群主有多少钱
        int leftMoney=super.getMoney();//群主当前的余额
        if(totalMoney>leftMoney){
            System.out.println("余额不足!");
            return redList;//返回空集合
        }

        //扣钱,其实就是重新设置余额,super.setXX方法
        super.setMoney(leftMoney-totalMoney);

        //发红包,需要平均拆分为count份
        int avg=totalMoney / count;
        int mod=totalMoney % count; //余数,也就是甩下的零头
        //剩下的零头,包在一个最后一个红包当中
        //下面把红包一个一个放在集合当中
        for (int i = 0; i < count-1; i++) {
            redList.add(avg);
        }
        int last=avg+mod;
        redList.add(last);
        return redList;
    }
}

//普通成员的类
class Member extends User{
    public Member() {
    }

    public Member(String name, int money) {
        super(name, money);
    }

    public void receive(ArrayList<Integer> list){
        //从多个红包中随便抽取一个,给我自己
        //随机获取一个集合中的索引编号
        int index=new Random().nextInt(list.size());
        //根据索引,从集合中删除,并且得到被删除的包,给我自己
        int delta=list.remove(index);
        //当前成员自己有多少钱
        int money=super.getMoney();
        //加法,重新设置回去
        super.setMoney(money+delta);
    }
}

三、多态

1、接口:是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么 接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法 (JDK 9)。
接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并 不是类,而是另外一种引用数据类型。接口可以多实现。
在这里插入图片描述
2、多态是继封装、继承之后,面向对象的第三大特性。 生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也 是不一样的。可见,同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。
前提【重点】:
1)继承或者实现【二选一】
2)方法的重写【意义体现:不重写,无意义】
3)父类引用指向子类对象【格式体现】

多态的好处:实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展 性与便利。
代码如下:

//定义父类:
public abstract class Animal { 
	public abstract void eat(); 
}
//定义子类:
class Cat extends Animal { 
	public void eat() { 
		System.out.println("吃鱼"); 
	} 
}class Dog extends Animal { 
	public void eat() { 
		System.out.println("吃骨头"); 
	} 
}
//定义测试类:
public class Test { 
	public static void main(String[] args) { 
	// 多态形式,创建对象 
	Cat c = new Cat(); 
	Dog d = new Dog(); 
	// 调用showCatEat showCatEat(c); 
	// 调用showDogEat
	showDogEat(d);
	/*以上两个方法, 均可以被showAnimalEat(Animal a)方法所替代 而执行效果一致 */
	showAnimalEat(c); 
	showAnimalEat(d); 
	}
	public static void showCatEat (Cat c){ 
		c.eat(); 
	}
	public static void showDogEat (Dog d){ 
		d.eat(); 
	}
	public static void showAnimalEat (Animal a){ 
		a.eat(); 
	} 
}

由于多态特性的支持,showAnimalEat方法的Animal类型,是Cat和Dog的父类类型,父类类型接收子类对象,当 然可以把Cat对象和Dog对象,传递给方法。 当eat方法执行时,多态规定,执行的是子类重写的方法,那么效果自然与showCatEat、showDogEat方法一致, 所以showAnimalEat完全可以替代以上两方法。 不仅仅是替代,在扩展性方面,无论之后再多的子类出现,我们都不需要编写showXxxEat方法了,直接使用 showAnimalEat都可以完成。 所以,多态的好处,体现在,可以使程序编写的更简单,并有良好的扩展。

四、String的不变性如何理解

字符串不变:字符串的值在创建后不能被更改。
以下面代码为例:

String s1 = "hello"; 
s1 += "word"; 
System.out.println(s1); // "helloword" 

既然说String不可变,为什么hello后面连接word之后又变成helloword了,不是连接后还是hello吗?
实际上内存中有"hello",“helloword"两个对象,s1从指向"hello”,改变指向,指向了"helloword"。
在这里插入图片描述

五、static关键字的含义

关于 static 关键字的使用,它可以用来修饰的成员变量和成员方法,被修饰的成员是属于类的,而不是单单是属于某个对象的。也就是说,既然属于类,就可以不靠创建对象来调用了。
当 static 修饰成员变量时,该变量称为类变量。该类的每个对象都共享同一个类变量的值。任何对象都可以更改 该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行操作。
比如说,基础班新班开班,学员报到。现在想为每一位新来报到的同学编学号(sid),从第一名同学开始,sid为 1,以此类推。学号必须是唯一的,连续的,并且与班级的人数相符,这样以便知道,要分配给下一名新同学的学 号是多少。这样我们就需要一个变量,与单独的每一个学生对象无关,而是与整个班级同学数量有关。 所以,我们可以这样定义一个静态变量numberOfStudent,代码如下:

public class Student { 
	private String name; 
	private int age; 
	// 学生的id 
	private int sid; 
	// 类变量,记录学生数量,分配学号 
	public static int numberOfStudent = 0;
	public Student(String name, int age){ 
	this.name = name; 
	this.age = age; 
	// 通过 numberOfStudent 给学生分配学号 
	this.sid = ++numberOfStudent; 
	}
	// 打印属性值 
	public void show() { 
		System.out.println("Student : name=" + name + ", age=" + age + ", sid=" + sid ); 
	} 
}
public class StuDemo { 
	public static void main(String[] args) { 
		Student s1 = new Student("张三", 23); 
		Student s2 = new Student("李四", 24); 
		Student s3 = new Student("王五", 25);
		Student s4 = new Student("赵六", 26); 
		s1.show(); // Student : name=张三, age=23, sid=1 
	    s2.show(); // Student : name=李四, age=24, sid=2 
	    s3.show(); // Student : name=王五, age=25, sid=3 
	    s4.show(); // Student : name=赵六, age=26, sid=4 
	} 
}

如果感兴趣可以再去掉public static int numberOfStudent = 0;中的static运行下看下结果有什么区别。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值