1.练习回顾
定义商品对象数组,实现商品的添加和查询:
商品类: 商品名字,商品价格
①测试类:
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Goods[] goods = new Goods[10];
String name;
Double price;
int count =0;
while (true){
System.out.println("请选择:1.添加商品 2.查询商品 3.退出 4.按商品价格排序");
int n = scanner.nextInt();
switch (n){
case 1:
System.out.print("请输入商品名:");
name = scanner.next();
System.out.print("请输入商品价格:");
price = scanner.nextDouble();
goods[count++] = new Goods(name,price);
break;
case 2:
System.out.print("商品名\t"+"价格\n");
for (int i = 0; i < count; i++) {
System.out.print(goods[i].name+"\t");
System.out.print(goods[i].price+"\n");
}
break;
case 3:
return;
case 4:
for (int i = 1; i < count; i++) {
for (int j = 0; j < count-i; j++) {
if(goods[j].price>goods[j+1].price){
Goods good = goods[j];
goods[j]=goods[j+1];
goods[j+1]=good;
}
}
}
break;
default:
break;
}
}
}
}
②.商品类
public class Goods {
String name;
Double price;
public Goods(String name, Double price) {
this.name = name;
this.price = price;
}
}
2.封装
2.1什么是封装?
封装,即隐藏对象的属性和实现细节,仅对外公开接口(方法/函数),控制在程序 中属性的读和修改的访问级别;将抽象得到的数据和行为(或功能)相结合,形成一个 有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中属性 数据和函数都是类的成员。 封装的目的:是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要 通过外部接口,以特定的访问权限来使用类的成员。
2.2 java中的封装
广义来说:一切公共代码的抽取都可以叫封装; 一般体现在公共方法的封装:工具类。
狭义来说(属性封装):隐藏对象的属性和实现细节;
①将属性私有化 ,使用private关键字修饰;
②为使用private关键字修饰的属性添加 getter和setter方法,通过get和set方法来操作属性;
③在setter方法中,添加数据的逻辑校验。
实例:
public class Student {
private String name;
private int age;
public Student(){}
public Student(String name,int age){
//this.name=name;
//this.age=age;
this.setName(name);
this.setAge(age);
}
public void introduce() {
System.out.println(this.name+" "+this.age);
}
//提供针对属性操作的getter,setter方法
//setter方法:用于设置属性值
public void setName(String name){
this.name=name;
}
//getter方法:用于获取属性值
public String getName(){
return this.name;
}
//针对年龄的getter,setter
public void setAge(int age){
//在setter方法中添加判断逻辑
if (age<0 ||age >120){
System.out.println("年龄不合法,无法设值");
}else {
this.age = age;
}
}
public int getAge(){
return this.age;
}
}
public class Test {
public static void main(String[] args) {
//创建学对象
//Student s = new Student();
//s.name="张三";
//s.age=-18;
//自我介绍
//s.introduce();
//属性封装:针对属性进行保护,避免出现非法数据
//问题:因为可以直接访问属性,导致进行非法赋值
//解决:1.将属性变为私有
// 2.提供针对属性的getter,setter方法
// 3.在setter方法中添加判断逻辑
Student s = new Student();
s.setName("张三");
s.setAge(-18);
//System.out.println(s.getName());
//System.out.println(s.getAge());
s.introduce();
//调用构造赋值
Student s2 = new Student("李四",-20);
s2.introduce();
}
}
3. 继承
3.1 什么是继承
3.2 为什么需要继承
3.3 继承的语法格式
//extends:继承 儿子继承父亲,可以拥有父类非私有的属性和方法
public class Son extends Father
3.4 方法重写 @Override注解
什么是方法重写
方法重写和方法重载的区别:
重载(overload) :发生在同一个类中 , 方法名相同,参数列表不同,不考虑返回值;重写(overrides) :发生在父子类中,子类继承父类的方法,方法名相同,参数也相同,但是实现方法体不同。
重写的注意事项:① 必须保证父子类中重写的方法,方法名相同,参数列表相同;②子类方法的返回值必须小于或等于父类方法的返回值范围;③ 子类方法的权限必须要大于等于父类方法的权限(不包括 private);④ 子类重写方法异常声明必须是父类的异常或子级异常;⑤ 私有的不能被继承。
toString()方法:
任何类都是Object类的直接子类或者间接子类,在Object类中有一个toString()方法,当输出一个对象时,先调用 当前类 的toString()方法,如果当前类没有toString() ,就去找当前类的 父类 ,看是否有toString()方法,如果过父类也没有,就去找 Object类 中的toString()方法并运行。
数据模型类包含:成员属性私有化,成员方法,构造方法,get/set方法 ,toString()
3.5 super关键字(父类对象),this关键字(当前类对象)
super 关键字的用法:①在子类的成员方法中访问父类的成员变量和成员方法;②在子类的构造方法中访问父类的构造方法。
3.6 继承中构造方法的特点
①构造方法不能被继承(构造方法是一个类独有的方法);
②创建子类对象一定是先调用父类构造,再调用子类构造;(并且只有子类构造才能调用父类构造)
③子类构造可以通过super关键字调用父类有参构造,有参super(参数列表);
④super父类构造调用,必须是子类构造中的第一行语句,并且一个子类构造,只能调用一次super();必须先有父再有子。
继承的特点: java中类与类之间是单继承的,但是可以多级继承,一个父类可以有多个子类。
public class Father {
int money = 500;
public Object liveHouse(){
System.out.println("住80年代红砖瓦房.....");
return "xxx";
}
}
//extends:继承 儿子继承父亲,可以拥有父类非私有的属性和方法
public class Son extends Father{
//overrides(重写):子类可以重写父类方法
public String liveHouse(){
System.out.println("住1000万海景洋房....");
return "aaa";
}
//儿子可以有自己的方法
public void driveCar(){
System.out.println("儿子开跑车");
}
}
public class Test {
public static void main(String[] args) {
Son son = new Son();
System.out.println("儿子有钱:"+son.money);
//儿子重写了父类方法,此时调用的是子类方法
son.liveHouse();
son.driveCar();
//overrides(方法重写)
//子类继承父类,定义与父类一样的方法,则称为子类重写了父类方法
//重写方法的特征
//a.子类方法与父类方法的方法名一样,参数一样(个数,类型,次序)
//b.子类方法的返回值必须和父类保持一致,子类的返回值要么与父类一样,或者是父类返回值的子类
//c.子类方法的访问修饰符,必须等于或大于父类方法的访问修饰符
//d.子类方法抛出的异常声明,不能超出父类异常声明的范围
//overload(方法重载)
//在同一个类中,方法名相同,参数不同(个数,类型,次序)
//与参数名,返回值,访问修饰符无关
//在继承关系中,要满足,先满足先有父,再有子的原则(无父无子)
//1.在父子继承关系中,当创建子类对象的时候,会默认调用父类的无参构造,先创建父类对象
//2.如果父类没有无参构造,此时需要在子类构造中的第一行代码处,显示调用父类构造
}
}
小结
1. 继承关键字:extends2. 单继承,一个类只能有一个直接父类3. 子类可以继承父类:public protected 同包默认的属性和方法,不能继承private私有方法4. 子类可以书写自己的属性和方法5. 子类可以重写父类的方法6. 在子类中可以通过super调用父类的方法和属性。super.方法名/属性名
无父无子:
a. 父类构造不能继承,但是必须调用b. new子类的时候,子类构造的 第一行必须调用父类的构造 方法 c.如果子类不写super(),系统默认调用父类无参构造d.可以通过super(参数)调用有参,并且必须第一行,并且只能有一个super()。
通过子类调用方法,子类重写方法则调用自己的方法,如果子类没有重写方法则使用父类的方法。
继承的作用:A. 减少代码冗余B. 书写一个父类,子类可以对父类进行扩展C. 子类可以对父类重新定义