0720(013天 面向对象编程基础03-继承)
每日一狗(一只明智的生活)
面向对象编程基础03-继承
文章目录
封装巩固(复数类)
package com.ketang;
public class FuShu {
private double shiBu;
private double xuBu;
// (a+bi)+(c+di)=(a+c)+(b+d)i。
public FuShu add(FuShu num) {
double num1 = num.getShiBu() + this.getShiBu();
double num2 = num.getXuBu() + this.getXuBu();
FuShu res = new FuShu();
res.setShiBu(num1);
res.setXuBu(num2);
return res;
}
// (a+bi)(c+di)=(ac-bd)+(bc+ad)i
public FuShu cheng(FuShu num) {
double num1 = this.getShiBu() * num.getShiBu() - this.getXuBu() * num.getXuBu();
double num2 = this.getShiBu() * num.getXuBu() + this.getXuBu() * num.getShiBu();
FuShu res = new FuShu();
res.setShiBu(num1);
res.setXuBu(num2);
return res;
}
public String show() {
String res1 = shiBu + "";
String res2 = "+" + xuBu + "i";
if (shiBu == 0) {
res1 = "";
res2 = xuBu + "i";
}
if (xuBu < 0) {
res2 = xuBu + "i";
} else if (xuBu == 0) {
res2 = "";
}
return res1 + res2;
}
public double getShiBu() {
return shiBu;
}
public void setShiBu(double shiBu) {
this.shiBu = shiBu;
}
public double getXuBu() {
return xuBu;
}
public void setXuBu(double xuBu) {
this.xuBu = xuBu;
}
}
/
package com.ketang;
public class T02复数乘法 {
public static void main(String[] args) {
// TODO Auto-generated method stub
FuShu fs1 = new FuShu();
fs1.setShiBu(1);
fs1.setXuBu(2);
FuShu fs2 = new FuShu();
fs2.setShiBu(5);
fs2.setXuBu(3);
System.out.println(fs1.show()); // 1.0+2.0i
System.out.println(fs2.show()); // 5.0+3.0i
System.out.println(fs1.cheng(fs2).show()); // -1.0+13.0i
}
}
1. 继承
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类 继承方法,使得子类具有父类相同的行为。
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也 可以用父类的功能,但不能选择性地继承父类。
继承是is-a的相互关系
-
单继承,所有类只能有一个父类。
-
所有类的起源都是java.long.Object类。
-
就是子类继承父类的特征和行为
案例
package com.ketang;
public class Person {
public static void main(String[] args) {
Student stu = new Student();
stu.name = "张三"; // 子类可以拥有父类的部分属性和方法
stu.eat();
// stu.worker(); // 找不到私有方法
}
protected String name;
protected void eat() {
System.out.println(name + "在吃饭");
}
private void worker() {
System.out.println(name + "有工作");
}
}
class Student extends Person {
}
1.1 优点
- 可以对父类的属性进行修改扩展。(属性或方法就近原则)
- 拥有所有父类可被继承的属性和方法,避免冗余代码,提高开发效率
1.2 缺点
- 父变则子比变
- 继承破坏了封装,对子类而言,父类的所有实现细节和属性都是透明的
- 继承是一种强耦合关系
2. 特殊关键字(包)
2.1 包package
类或接口的容器,是一个用于避免命名冲突
的名空间,是一个逻辑命令的概念,于具体的物理位置无关
在具体的实现中,包名称经常和目录名称对称。
扩展控制命名空间
2.2 什么是包
一般情况下会发现于自己建的包一样的文件名结构,这样主要是方便管理,在ide工具中拖动类,工具会自动识别并修改包名,但是在文件夹中直接移动源文件,文件管理器可没那么高级。
命名规范:
- 全小写
- 域名翻转:
com.lanou
包的作用
- 包能将相关的源代码文件组织在一起
- com.yanan.dao其中存放操作数据库相关的类文件
- com.yanan.biz存放相关的业务类文件
- 包减少了名称冲突带来的问题
- 可以使用package指明源文件中的类属于哪个具体的包
包的使用
- 懒得导包就得写全类名
com.gongju.MyDate
- 使用import进行导包,可以只使用类名进行调用(java中没有重命名这一说)
- 懒人导包法
import com.gongju.*; // 将包中的所有类到了进去
- 懒人导包法
2.3 导包
默认类不用导
- java.long
import 类的全名
默认包中的所有类只能同包访问,不允许其他类进行访问,默认包可以访问其他包中的东西
2.4 包说明
package-info.java文件用来说明这个包
- 这个文件中不能定义公共的和私有的,可以定义默认的类及包常量,提供给包下面的类进行共享
- 适合放一些在包内共享的数据或方法
环境变量CLASSPATH
jdk8或者以前的版本中需要配置环境变量CLASSPATH
jdk11或17中不需要
3. 一种思想(抽象)
忽略掉一个对象或实体的细节而只关注其本质特征的过程,可以简化功能与格式,帮助用户与对象交互 是人类解决问题的基本法宝。良好的抽象策略可以控制问题的复杂程度,增强系统的通用性和可扩展性 抽象主要包括过程抽象和数据抽象。
- 过程抽象是将问题域中具有明确功能定义的操作抽取出来,并将其作为一个实体看待
- 数据抽象是较过程抽象更高级别的抽象方式,将描述客体的属性和行为绑定在一起,实现统一的抽象,从而达到对现实世界客体的真正模拟
对象对象编程的核心是面向抽象编程,面向抽象编程的核心是面向接口编程
扩展小芝士
-
方法平起平坐,方法内部不能嵌套方法。
-
方法形参没有默认值
-
私有属性是否可被继承
- 网上有两种(可以或者不可以)
- 可以继承但是不能直接访问
-
面向切面(官:方面)编程
-
待整理
-
Java安全:没有获取地址的方法,可获取就可操作(待整理)
-
equals()比较的是引用值(地址的哈希值)
-
随机访问:通过下标可以随机访问
-
栈和堆
栈 缺点:存储长度一致 优点:快速定位 堆 优点:想要多大内存就有多大内存 缺点:定位元素困难且慢 缝合怪 栈来存储变量名-堆的存储地址
-
私有是指类内私有,不是对象内私有,可以再类内获取到另一个同类对象的私有属性或方法
-
支持预览的文件不要将多数文件存放至一个文件夹内,可以建立多层文件,就能高速存储。
-
自定义引用类型的初始值为空指针(null)
-
面试时三大特性再加一个叫抽象
课后作业
1、猜数游戏
// 实现类
package com.caishu;
import java.util.Scanner;
public class GuessGame {
private int target = (int) (Math.random() * 20 + 1);
private int[] history = new int[15];
private int count = 0;
private boolean zhengChang = true;
private boolean zhengQie = false;
public void start() {
Scanner sc = new Scanner(System.in);
System.out.println(target); // test
while (count < history.length) {
System.out.println("请输入第" + (count + 1) + "猜测的数据(-1退出)");
int tmp = sc.nextInt();
if (tmp == -1) {
zhengChang = false;
break;
}
String zhuangTai = input(tmp);
System.out.println(zhuangTai);
if (zhuangTai.equals("猜中了")) {
zhengQie = true;
break;
}
}
showHistory();
sc.close();
}
private void showHistory() {
if (zhengChang) {
if (count < 5) {
System.out.println("5次以内 秀");
} else if (count < 10) {
System.out.println("10次以内 不行呀");
} else if (count <= 15) {
System.out.println("15次以内 菜");
}
if (!zhengQie) {
System.out.println("没猜中 菜的雅痞");
}
for (int i = 0; i < count; i++) {
System.out.println("第" + (i + 1) + "次猜数为" + history[i]);
}
} else {
System.out.println("非正常退出");
}
}
private String input(int num) {
history[count++] = num;
String res = "";
if (num > target) {
res = "猜大了";
} else if (num < target) {
res = "猜小了";
} else {
res = "猜中了";
}
return res;
}
public void setTarget(int target) {
this.target = target;
}
public int[] getHistory() {
return history;
}
public void setHistory(int[] history) {
this.history = history;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
// 测试类
package com.caishu;
public class Test01 {
public static void main(String[] args) {
GuessGame gg = new GuessGame();
gg.start();
}
}
2、计算圆的面积和周长,输入半径值
属性:
半径
方法:
周长
面积
// 实现类
package com.yuan;
public class Yuan {
private double r; // 半径
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
public double getZhouChang() {
return 2 * Data.PI * r;
}
public double getMianJi() {
return Data.PI * r * r;
}
}
// 数据类
package com.yuan;
class Data {
static final double PI = 3.14;
}
// 测试类
package com.yuan;
public class Test01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Yuan yuan1 = new Yuan();
yuan1.setR(3);
System.out.println(yuan1.getZhouChang()); // 18.84
System.out.println(yuan1.getMianJi()); // 28.259999999999998
}
}
3、请定义一个交通工具Vehicle的类,其中有:
属性:
速度(speed):人为限定在200以内
车的类型(type);
方法:
移动(move())
设置速度(setSpeed(double s))
加速speedUp(double s)
减速speedDown(double s)
最后在测试类Vehicle中的main()中实例化一个交通工具对象,
并通过构造方法给它初始化speed,type的值,并且打印出来。另外,调用加速,减速的方法对速度进行改变。
// 实现类
package com.yuan;
public class Vehicle {
private double speed; // 速度
private String type; // 车的类型
public Vehicle() {
}
public Vehicle(double speed, String type) {
this.speed = speed;
this.type = type;
}
public void move() {
System.out.println("您移动了一下您的爱车:" + type);
}
public String show() {
return "车型:" + type + ",车速:" + speed;
}
public double getSpeed() {
return speed;
}
public void speedUp(double s) {
setSpeed(this.speed + s);
}
public void speedDown(double s) {
setSpeed(this.speed - s);
}
public void setSpeed(double speed) {
if (speed > 200) {
speed = 200;
} else if (speed <= 0) {
speed = 0;
}
this.speed = speed;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
// 测试类
package com.yuan;
public class Test02 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Vehicle che1 = new Vehicle(30, "谷神");
System.out.println(che1.show()); // 车型:谷神,车速:30.0
che1.setSpeed(50);
System.out.println(che1.show()); // 车型:谷神,车速:50.0
che1.move(); // 您移动了一下您的爱车:谷神
che1.speedDown(20);
System.out.println(che1.show()); // 车型:谷神,车速:30.0
che1.speedUp(10);
System.out.println(che1.show()); // 车型:谷神,车速:40.0
}
}