封装
概述:面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外部无法直接操作和修改。封装可以认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。 要访问该类的数据,必须通过指定的 方式。适当的封装可以让代码更容易理解与维护,也加强了代码的安全性。
原则: 将属性隐藏起来,若需要访问某个属性,提供公共方法对其访问。
封装步骤:
1、使用 private 关键字来修饰成员变量。
2.、对需要访问的成员变量,提供对应的一对 getXxx 方法 、 setXxx 方法。
封装的操作—private关键字
private关键字含义:
1. private是一个权限修饰符,代表最小权限。
2. 可以修饰成员变量和成员方法。
3. 被private修饰后的成员变量和成员方法,只在本类中才能访问。
示例:
package array;
public class Method {
private String name; //private修饰的成员变量
private int age;
private double score;
public void setName(String a) {
String name = "langlang";
}
public String getName() {
return name;
}
public void setAge(int b) {
int age = 12;
}
public int getAge() {
return age;
}
}
封装优化1—this关键字
this的含义:代表所在类的当前对象的引用(地址值),即对象自己的引用。
铭记: 方法被哪个对象调用,方法中的this就代表哪个对象。即谁在调用,this就代表谁。
格式
this.成员变量名;
package array;
public class Students {
private String name; //private修饰的成员变量
private int age;
private double score;
public void setName(String name) {
this.name=name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
调用方法,输出结果
package array;
public class Test_1 {
public static void main(String[] args){
Students lll= new Students(); //构造一个新的方法lll代替另一个类Students;
lll.setName("langyongling"); //setName方法里变量赋值
System.out.println(lll.getName());
lll.setAge(12);
System.out.println(lll.getAge());
}
}
封装优化2—构造方法
作用:构造方法用来初始化一个新建的对象,给对象的成员变量赋初始值。
格式:
修饰符 构造方法名(参数列表){
// 方法体
}
示例:
package array;
public class Students {
private String name; //private修饰的成员变量
private int age;
private double score;
public Students(){ //无参构造方法
}
public Students(String namme,int age){ //有参构造方法,且是方法的重载
this.name=name;
this.age=age;
this.score=score;
}
}
javabean
1、JavaBean 是 Java语言编写类的一种标准规范。
2、符合 JavaBean 的类,要求类必须是具体的和公共的,并且具有无 参数的构造方法,提供用来操作成员变量的 set 和 get 方法。
示例:符合JavaBean的类
package array;
public class Students {
private String name; //private修饰的成员变量
private int age;
private double score;
public Students() { //无参构造方法
}
public Students(String namme, int age) { //有参构造方法,且是方法的重载
this.name = name;
this.age = age;
this.score = score;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
继承
基础知识
定义: 就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。
优点:
1. 提高代码的复用性。
2. 类与类之间产生了关系,是多态的前提。
格式:
class Father{
//方法体;
}
class Son extends Father{
//方法体;
}
示例:
//父类
package moreclass;
public class Father {
String name ;
int age;
public void getName(){
System.out.println("name"+":"+name);
}
public void getAge(){
System.out.println("age"+":"+age);
}
}
//子类继承父类
package moreclass;
public class Son extends Father {
String sex;
public void sex() {
System.out.println("sex" + ":" + sex);
}
}
//实例化对象
package moreclass;
public class GetName {
public static void main(String[] args) {
Son s = new Son();
s.name="langyongling";
s.sex="女";
s.age=12;
s.getName();
s.getAge();
s.sex();
}
}
继承后的特点——成员变量
1、成员变量不重名(参照上面示例)
相互之间不影响,并正确输出结果。
2、成员变量重名
package moreclass;
public class Father {
String name ;
int age;
public void age(){
System.out.println(age);
}
}
package moreclass;
public class Son extends Father {
String name;
public void sameName() {
System.out.println("name" + ":" + this.name);
System.out.println("name" + ":" + super.name);
}
}
package moreclass;
public class GetName {
public static void main(String[] args) {
Son s = new Son();
Father f = new Father();
s.name="langyongling";
f.name="wangbin";
s.age=11;
s.sameName();
s.age();
}
}
1、成员方法重名—重写(override)
定义:子类中出现和父类相同的方法名,传参类型和数量,会出现覆盖效果,称为方法的重写,声明不变,重新实现前提条件:方法在两个不同的类中,且这两个类之间有继承关系
示例:
package moreclass;
public class Father {
String name;
int age;
public void name() {
String name = "wangbin";
System.out.println(name);
}
public void age(int a) {
System.out.println(age);
}
}
//子类
package moreclass;
public class Son extends Father {
String name;
public void name(){
String name1="langlang";
String name2="xiaokeai";
System.out.println(name1);
System.out.println(name2);
}
}
//调用方法,运行结果
package moreclass;
public class GetName {
public static void main(String[] args) {
Son s = new Son();
s.name();
}
}
结果:
说明:子类和父类都有相同的方法name(),属于方法的重写。子类方法覆盖父类方法,所以调用运行的结果是子类方法的运行结果。
继承后的特点——构造方法
- 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
2. 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个 super() ,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。
父类构造方法示例:
子类调用父类的构造方法: ```java package moreclass;public class Father {
String name;
int age;
Father(){
System.out.println("hahah");
}
}
public class Son extends Father { String name; Son() { super(); //子类调用父类的构造方法 System.out.println(“wwooeo”); }
}
public class GetName { public static void main(String[] args) { Son s = new Son(); //实例化对象 } }
运行结果:<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/21882085/1625410376144-fcdf738f-ee6b-44a5-b2e2-18b4b2092fbe.png#clientId=u2b2c0eac-abf5-4&from=paste&height=163&id=u6fbb2717&margin=%5Bobject%20Object%5D&name=image.png&originHeight=163&originWidth=890&originalType=binary&ratio=1&size=12498&status=done&style=none&taskId=uea6903d1-7913-4441-a11c-316dec2be9d&width=890)
<a name="oKNDW"></a>
#### super和this
super:代表父类的存储空间标识(父类的引用)<br />this:代表当前对象的引用<br />用法<br />1、访问成员
```java
this.成员变量 //当前类
super.成员变量 //父类
this.方法名() //当前类
super.方法名() //父类
示例:
public class Father {
String name;
String sex;
public void sex() {
String sex="男";
System.out.println(sex);
}
}
//子类
public class Son extends Father {
String sex;
public void sex(){
String sex="女";
System.out.println(sex);
}
public void sex1(){
this.sex(); //调用当前类方法
super.sex(); //调用父类方法
}
}
//调用方法
public class GetName {
public static void main(String[] args) {
Son s = new Son();
s.sex1();
}
}
继承的特点
1、java只支持单继承,不支持多继承(即只能有一个父类)
2、Java支持多层继承
class A
class B extends A {}
class C extends B {}
3、子类和父类是一种相对的概念
抽象类
由来:父类中的方法,被它们的子类重写,子类各自实现的都不尽相同。父类的方法声明和方法主体,只有声明还有意义,而方法主体已经没有意义了。所以把没有方法主体的方法称为抽象方法,包含抽象方法的类为抽象类。
抽象方法:使用abstract关键字修饰的方法。
抽象方法只包含一个方法名而没有方法体。
格式:
修饰符 abstract 返回值类型 方法名(参数)
如果一个类包含抽象方法,那么这个类就一定是抽象类
public abstract class man{
public abstract int age(int a){
}
}
抽象的使用
1、继承抽象类的子类必须重写父类中所有的抽象方法
2、必须由子类实现该父类的抽象方法
实例:
//父类
package moreclass;
public abstract class Father { //抽象类
public abstract void sex(); //抽象方法,无方法体
}
//子类
package moreclass;
public class Son extends Father {
public void sex(){
System.out.println("男");
};
}
//子类方法调用并执行
package moreclass;
public class GetName {
public static void main(String[] args) {
Son s = new Son();
s.sex();
}
}
结果:
此时的方法重写,是子类对父类抽象方法的完成实现,我们将这种方法重写的操作,也叫做实现方法。
抽象类的使用
- 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。
2. 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。
3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。
4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。
理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义 。
总结案例:群主发普通红包
群主发普通红包。某群有多名成员,群主给成员发普通红包。普通红包的规则:
1. 群主的一笔金额,从群主余额中扣除,平均分成n等份,让成员领取。
2. 成员领取红包后,保存到成员余额中。
请根据描述,完成案例中所有类的定义以及指定类之间的继承关系,并完成发红包的操作。
根据案例,理出逻辑关系
User类(父类):
package moreclass;
public class User {
private String name;
private double balance;
public User(){
}
public User(String name,double balance){
this.name=name;
this.balance=balance;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getBalance() {
return balance;
}
public void show() {
System.out.println("用户名:"+ name +" , 余额为:" + balance + "元");
}
}
群主类(子类):
package moreclass;
import java.util.ArrayList;
public class QunZhu extends User {
public QunZhu(){
}
public QunZhu(String name,double balance){
super(name,balance);
}
/*
群主发红包,就是把一个整数的金额,分层若干等份。
1.获取群主余额,是否够发红包.
不能则返回null,并提示.
能则继续.
2.修改群主余额.
3.拆分红包
*/
public ArrayList<Double> send(int money,int account){
double balance = getBalance(); //获取余额
if(money>balance){
return null;
}
setBalance(balance-money); //修改余额
ArrayList<Double> list = new ArrayList<>(); //ArrayList是集合,需要用引用数据类型,所以用但是Double,而不是double
double m = money/account;
for (int i = 0; i <account ; i++) {
list.add(m);
}
return list;
}
}
成员类(子类):
package moreclass;
import java.util.ArrayList;
import java.util.Random;
public class Member extends User {
public Member(){
}
public Member(String name,double balance){
super(name,balance);
}
public void kaihongbao(ArrayList<Double> list){
Random r = new Random(); // 创建Random对象
int index = r.nextInt(list.size()); // 随机生成一个角标
Double money = list.remove(index); // 移除一个金额
setBalance(money); // 直接调用父类方法,设置到余额
}
}
发红包:
package moreclass;
import java.util.ArrayList;
import java.util.Scanner;
public class FaHongBao {
public static void main(String[] args) {
QunZhu qz = new QunZhu("lang", 166);
// 定义一个键盘输入
Scanner sc = new Scanner(System.in);
System.out.println("请输入金额:");
int money = sc.nextInt();
System.out.println("请输入个数:");
int count = sc.nextInt();
// 发送红包
ArrayList<Double> send = qz.send(money, count);
if (send == null) {
System.out.println(" 余额不足...");
return;
}
// 创建三个成员
Member m = new Member("lang1",0);
Member m2 = new Member("lang2",0);
Member m3 = new Member("lang3",0);
// 打开红包
m.kaihongbao(send);
m2.kaihongbao(send);
m3.kaihongbao(send);
// 展示信息
qz.show();
m.show();
m2.show();
m3.show();
}
}
运行结果: