核心基础之面向对象编程
Java是第一大编程语言和开发平台。它有助于企业降低成本,缩短开发周期,推动创新以及改善应用服务。如今全球有数百万开发人员运行超过51亿个java虚拟机,java仍是企业和开发人员的首选开发平台
课程内容的介绍
1.面向对象思路
2.类和对象
3.局部变量和成员变量
4.值传递还是引用传递
5.匿名对象和构造方法
6.常见的关键字介绍
7.继承,封装,多态
8.访问权限修饰符和方法的重写
9.flnal关键字
10.抽象类和接口
11.内部类
一.面向对象思想概述
1.计算机编程语法的发展
面向对象编程2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GLoaGhj6-1652267195231)(C:\Users\11640\Pictures\Saved Pictures\mian.png)]
2.面向对象和面向过程的对比
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8N0dNUEl-1652267195232)(C:\Users\11640\Pictures\Saved Pictures\guo.png)]
3.面向过程思想概述
面向过程的思想去实现一个功能的步骤
首先要做什么,怎么做,最后我们在代码体现,一步一步去实现,而具体的每一步都需要我们去实现和操作。这些步骤相互调用和协作,实现我们的功能,每一个步骤我们都是参与者,并且需要面对具体的每一个步骤和过程,这就是面向对象最直接的体现。
面向过程开发关心的就是每一步的实现,如果每一步都能够实现那么功能就能够实现,中间如果任何一个步骤出现问题,都会导致失败。面向过程的代表语言:C语言
4.面向对象思想概述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9VUyMP9u-1652267195233)(C:\Users\11640\Pictures\Saved Pictures\gai.png)]
面向过程的编程思想只能满足简单功能的实现,但在实际开发当中,项目的功能只会越来越多,不会越来越少。需求也是不断地变化的,可随这需求的更改,功能的增多,发现需要面向每一个过程就很麻烦了,并且程序的可维护性也是非常非常差的,能不能把这每一个步骤和功能再进行封装,根据不同的功能,进行不同的封装,功能类似的封装在一起。使用的时候,找到对应的类就可以了。这就是面向对象的思想。
1.OOA:面向对象分析
2.OOD:面向对象设计
3.DDP:面向对象编程
5.面向对象编程初步
5.1如何开车
事物比较简单,可以用线性的思维去解决
面向过程:
1.踩离合
2.挂挡
3.踩油门,放离合
4.开了
面向对象:
1.驾驶员
2.汽车
3.驾驶员开汽车
5.2如何造汽车
事物比较复杂,使用简单的线性思维无法解决
面向过程:
1.造车轮
2.造发动机
3.造挡风玻璃
4.造车皮
5…
难点:很难决定上面这些步骤之间的关系!先造发动机还是先造车轮?
面向对象:
车轮
买橡胶
到马来西亚
找到橡胶厂
掏钱买
用船将橡胶运到国内
造磨具
将橡胶放入磨具
出轮胎
发动机
…
车壳
…
挡风玻璃
…
将上面的造出的东东,组装,汽车造出!
6.面向对象的好处
1.面向对象也是基于面向过程的编程思想,但是面向对象相比于面向过程更符合我们的思维方式,万物皆对象。
2.可以将复杂的问题简单化,大大提高了程序的可读性和可维护性
3.面向过程思想中,我们是程序的执行者,面向对象当中,我们是程序的调用者,这样的话可以方便程序给其他人调用,提高了程序的扩展性
7.面向对象的特征
1.封装(encapsulation)
2.继承(inheritance)
3.多态(polymorphism)
4.抽象(abstract)
二 .类和对象
现实世界是由什么组成的?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q4w7yuoD-1652267195234)(C:\Users\11640\Pictures\Saved Pictures\lei.png)]
世界是由对象组成的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fm6HYvho-1652267195234)(C:\Users\11640\Pictures\Saved Pictures\yue.png)]
1.类和对象的概念
对象: 是具体的事物
类:是对对象的抽象
对象:张三 ,李四 ,王五,赵六
抽取上述对象二的相同的部分:
年龄 身高 体重 打牌 打四川麻将 去隔壁老王家 下棋 做饭 打王者荣耀 吃鸡
天使类
四个天使:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GXL3KTXl-1652267195235)(C:\Users\11640\Pictures\Saved Pictures\tian.png)]
抽象U他们的共同特点
-
带翅膀(带翅膀的不一定是天使,也有可能是鸟人)
-
女孩
-
善良
2.java类描述事物
目前我们可以用计算机来表示八大基本数据类型,但是我们在开发的时候还要存储其他的数据,比如一个人,一条狗,一张图片,一个视频等等,这种情况我们应该怎么实现?
我们学习编程语言的目的是为了模拟现实世界的事物,实现信息化。其实呢在计算机中使用Java语言模拟实现时间是很简单的Java为我们提供了类,所以Java是通过类来描述世界的
现实生活中如何描述应该事物:
-
属性 该事物的特征描述
-
行为 方法,该事物的动作行为
举个例子描述:表示一条狗
-
属性 狗的品种 狗的颜色 狗的体重
-
行为 跳 叫 睡 吃
我们学习Java语言的最基本单位是类,在Java中使用类来描述事物
3.类和对象的关系
类:类是抽象的,是一种相关的属性和行为的结合,可以看出一个模板
对象:对象是具体的 是客观存在的实例,是该类事物具体体现
举例: 老婆 翠花=new 老婆();
类 :老婆是一个类
对象;new老婆();是一个对象,取了个名字叫翠花
引用 叫翠花相当与叫了老婆对象
对象的特征:
属性:对象具有的各个特征
每个 对象的每个属性都拥有特定的值
行为:对象执行的操作
对象:用来描述客观事物的一个实体,由一组属性的方法构成
类是抽象的概念,仅仅是模板,比如说:人
对象是一个你能看到见,摸得着的的具体实体
1. 类和对象的具体使用
4.1类的定义
类的理解:
-
类是用来描述现实事物的
-
类是抽象的
-
类是一个模板,是属性和方法的集合
-
类是Java中最基本的单位
-
Java中使用class来描述类
Java中使用class类描述类
1.成员变量表示就是事物的属性
2.成员方法表示就是事物的行为
语法格式:
[访问权限修饰符]class 类名{
成员变量;
成员方法;
}
定义一个类的步骤:
1.定义类名
2.编写类的属性
3. 编写类的方法
package com.bobo.oop;
/**
* @author xiaoye
* @date 2022/3/31 - 15:21
*/
public class OOPDemo01 {
/**
* 程序人口
* @param args
*/
public static void main(String[] args) {
//创建一个Dog对象
Dog wangcai =new Dog();
System.out.println(wangcai);
System.out.println(wangcai.dogname);
System.out.println(wangcai.age);
System.out.println(wangcai.Color);
wangcai.dogname="wangcai";
wangcai.age=3;
wangcai.Color="白色";
System.out.println(wangcai.dogname);
System.out.println(wangcai.age);
System.out.println(wangcai.Color);
// 成员方法调用g
wangcai.eat();
wangcai.jupm();
}
}
//String dogHobby:成员变量不能定义到类体之外
//定义一个Dog Java类
class Dog{
// ---定义相关属性
//姓名
//成员变量
String dogname;
// 年龄
int age;
//颜色
String Color;
//----定义相关的行为 方法
public void eat(){
System.out.println("--->"+dogname);//成员变量
String dogname="小黑";
System.out.println(dogname);//局部变量
return;
}
public void jupm(){
System.out.println("跳跃....");
}
4.2对象的创建和使用
4.2.1如何创建对象
类名 对象名=new 类名();
/**
* 程序人口
* @param args
*/
public static void main(String[] args) {
//创建一个Dog对象
Dog wangcai =new Dog();
System.out.println(wangcai);
}
}
4.2.2如何使用对象中的属性和方法
对象创建出来了,如何调用相关的属性和方法呢?在Java中引用对象的成员:使用‘.’进行操作
-
引用属性:对象名.属性
-
引用方法:对象名.方法名()
package com.bobo.oop;
/**
* @author xiaoye
* @date 2022/3/31 - 15:21
*/
public class OOPDemo01 {
/**
* 程序人口
* @param args
*/
public static void main(String[] args) {
//创建一个Dog对象
Dog wangcai =new Dog();
System.out.println(wangcai);
System.out.println(wangcai.dogname);
System.out.println(wangcai.age);
System.out.println(wangcai.Color);
wangcai.dogname="wangcai";
wangcai.age=3;
wangcai.Color="白色";
System.out.println(wangcai.dogname);
System.out.println(wangcai.age);
System.out.println(wangcai.Color);
// 成员方法调用g
wangcai.eat();
wangcai.jupm();
}
}
//String dogHobby:成员变量不能定义到类体之外
//定义一个Dog Java类
class Dog{
// ---定义相关属性
//姓名
//成员变量
String dogname;
// 年龄
int age;
//颜色
String Color;
//----定义相关的行为 方法
public void eat(){
System.out.println("--->"+dogname);//成员变量
String dogname="小黑";
System.out.println(dogname);//局部变量
return;
}
public void jupm(){
System.out.println("跳跃....");
}
}
4.2.3 课堂案例
1.编写一个学生类,输出学生相关的信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K4wMbigH-1652267195235)(C:\Users\11640\Pictures\Saved Pictures\xue.png)]
package com.bobo.oop;
/**
* @author xiaoye
* @date 2022/4/11 - 19:59
*/
public class oopdemo03 {
public static void main(String[] args) {
Student t=new Student();
t.name="张三";
t.age=23;
System.out.println("方法调用之前学生的信息:"+t.name+"/t"+t.age);
Damo02 d=new Damo02();
//调用了方法
d.chenge(new Student());
//new Damo02().chenge(t);
System.out.println("方法调用之后学生的信息:"+t.name+"/t"+t.age);
}
}
class Damo02{
public void chenge(Student s){
s.name="小明";
s.age=18;
System.out.println("方法调用时学生的信息:"+s.name+"/t"+s.age);
}
}
class Student{
String name;
int age;
}
2.编写一个教员类,输出相关的信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MWcaysKY-1652267195235)(C:\Users\11640\Pictures\Saved Pictures\jiao.png)]
package com.bobo.oop;
/**
* @author xiaoye
* @date 2022/3/31 - 20:15
*/
public class jiaoyuan {
public static void main(String[] args) {
jiao jiaoan=new jiao();
jiaoan.printInfo();
jiaoan.teachername="张三丰";
jiaoan.major="数学";
}
}
class jiao{
String teachername;
String course;
String major;
String teachingAge;
public void printInfo(){
System.out.println("teachername="+teachername
+"/t course;"+course
+"/t major;"+major
+"/t teachingAge"+teachingAge);
}
}
3.定义一个管理员类
1.定义一个管理员类Administrator
2.定义其相关的属性和方法
3.定义一个测试类TestAdministrator
4.创建两个管理员类的对象,并输出他们的信息
package com.bobo.oop;
/**
* @author xiaoye
* @date 2022/4/1 - 15:09
*/
/**
* 管理员类
* 属性:
* 账号
* 密码
*/
public class Admininstrator {
//账号
String userName;
//密码
String password;
/**
* 判断账号密码是否正确
* @return
*/
public boolean login(){
System.out.println("账号登入...");
if ("zhangsan".equals(userName)&&"123".equals(password)){
return true;
}
return false;
}
public void logout(){
System.out.println("退出登入");
}
}
package com.bobo.oop;
/**
* @author xiaoye
* @date 2022/4/20 - 21:27
*/
public class TestAdministrator {
public static void main(String[] args) {
/**
* 创建两个管理员类的对象,并输出他们的信息
* @param args
*/
Admininstrator admin=new Admininstrator();
admin.userName="zhangsan";
admin.password="123";
System.out.println(admin.userName+"/t"+admin.password);
Admininstrator root=new Admininstrator();
root.userName="lisi";
root.password="111";
System.out.println(root.userName+"/t"+rootpassword);
}
}
4.3 对象的内存分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7cbhq1JP-1652267195236)(C:\Users\11640\Pictures\Saved Pictures\dx.png)]
5.局部变量和成员变量
变量分为局部变量和成员变量,这两种类型的变量也是容易让大家混淆的地方,所以我们在此处详细介绍他们的区别:
5.1定义的位置不同
成员变量:定义在类体以内,方法体以外
局部变量:定义在方法体内或者声明在方法上(形参)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QMXT9sup-1652267195236)(C:\Users\11640\Pictures\Saved Pictures\ju.png)]
5.2在内存中的位置不同
成员变量:在堆内存中存储
局部变量:在栈区中存储
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OM1vNHy2-1652267195236)(C:\Users\11640\Pictures\Saved Pictures\zhan.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9dKV2tAt-1652267195237)(C:\Users\11640\Pictures\Saved Pictures\111.png)]
5.3初始化值不同
成员变量:有默认值
局部变量:没有默认值,所有局部变量在使用之前必须赋值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nJz7sbS4-1652267195237)(C:\Users\11640\Pictures\Saved Pictures\13.png)]
5.4生命周期不同
生命周期:一个变量从创建到销毁的全过程
成员变量:随着对象的创建而创建,随着对象的销毁而销毁,具体的结束时间是在垃圾回收器空闲的时候而销毁
局部变量:随着方法的调用而创建,随着方法的执行结束而销毁
5.5当局部变量和成员变量重名的时候
当局部变量和成员变量重名的时候,局部变量优先于成员变量(就近原则)
package com.bobo.oop;
/**
* @author xiaoye
* @date 2022/3/31 - 15:21
*/
public class OOPDemo01 {
/**
* 局部变量和成员变量
* @param args
*/
public static void main(String[] args) {
Dog wangcai =new Dog();
System.out.println(wangcai);
System.out.println(wangcai.dogname);
System.out.println(wangcai.age);
System.out.println(wangcai.Color);
wangcai.dogname="wangcai";
int x;
int y;
System.out.println(wangcai.dogname);
System.out.println(wangcai.age);
System.out.println(wangcai.Color);
// 成员方法调用g
wangcai.eat();
wangcai.jupm();
}
}
//String dogHobby:成员变量不能定义到类体之外
//定义一个Dog Java类
class Dog{
// ---定义相关属性
//姓名
//成员变量
String dogname;
// 年龄
int age;
//颜色
String Color;
//----定义相关的行为 方法
public void eat(){
System.out.println("--->"+dogname);//成员变量
String dogname="小黑";
System.out.println(dogname);//局部变量
return;
}
public void jupm(){
System.out.println("跳跃....");
}
}
6.值传递和引用传递
6.1基本数据类型
基本数据类型作为形式参数,形参的改变不会影响实际参数,传递的是值本身
package com.bobo.oop;
/**
* @author xiaoye
* @date 2022/4/11 - 19:59
*/
public class oopdemo03 {
public static void main(String[] args) {
Demo d=new Demo();
int x=10
System.out.println("方法调用之前学X的值为:"+ x);// 10
d.chenge(x);//调用Demo对象的方法
System.out.println("方法调用之后x的值:"+ x);//10
}
}
class Damo02{
public void chenge(int a){
a +=5;//局部变量
System.out.println("方法调用时a的值:"+a);//15
}
}
输出结果
方法调用之前x的值:10
方法中x的值:15
方法调用之后x的值:10
6.2引用数据类型
引用数据类型作为参数,形参的改变影响实际参数,传递的是地址值
package com.bobo.oop;
/**
* @author xiaoye
* @date 2022/4/11 - 19:59
*/
public class oopdemo03 {
public static void main(String[] args) {
Student t=new Student();
t.name="张三";
t.age=23;
System.out.println("方法调用之前学生的信息:"+t.name+"/t"+t.age);
Damo02 d=new Damo02();
//调用了方法
d.chenge(new Student());
//new Damo02().chenge(t);
System.out.println("方法调用之后学生的信息:"+t.name+"/t"+t.age);
}
}
class Damo02{
public void chenge(Student s){
s.name="小明";
s.age=18;
System.out.println("方法调用时学生的信息:"+s.name+"/t"+s.age);
}
}
class Student{
String name;
int age;
}
输出结果
方法调用之前学生的信息:张三 23
方法调用时学生的信息:小明 18
方法调用之后学生的信息:张三 23
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y7NYncfg-1652267195237)(C:\Users\11640\Pictures\Saved Pictures\14.png)]
7.匿名对象
没有名次的对象我们称为匿名对象
new Dog();
new Demo02().chenge(new Student());
匿名对象的特点:对象只会被使用一次,作为调用者来说,之后就获取不到这个对象了
如果对象只需要使用一次的话,那么我们就可以使用匿名对象
匿名对象一旦使用完成就会自动释放,节约内存资源
作为实际参数传递的对象会比较方便。
三.常见的几个关键字
1.封装(private)
隐藏对象的属性和方法的实现,仅对外提供公共访问的方式。
特点:
1.隐藏了功能实现的过程,外界只需要通过公共的访问方式即可。
2.提高了代码的复用性
3.提高了程序的安全性
封装的步骤
1.将不需要对外提供的属性和方法封装起来
2.属性隐藏后提供对外访问的接口
2. private
peivate关键字是一个访问权限修饰符
private关键字的特点:
1.修饰的成员不能被外界直接访问
2.虽然不能被外部访问,但是可以在本类中是可以直接访问的
private的使用
1.将不需要对外访问的属性加上private关键字,同时给出公用的getter/setter方法
2.将本类构造方法加上private关键字,拒绝外界直接创建对象。
package com.bobo.oop;
/**
* @author xiaoye
* @date 2022/4/13 - 13:56
*/
public class OOPDamo04 {
public static void main(String[] args) {
User user=new User();
// user.Username="张三";
// user.age=18;
user.setAge(22);
user.setUsername("李四");
//System.out.println(user.Username+" "+user.age);
System.out.println(user.getAge()+"/t"+user.getUsername());
}
}
/**
* 在Java类中
* 类体以内及方法体以外 我们不能写逻辑代码!
*/
class User{
//外部不能访问,但是本类是可以访问的
private String Username;
private int age;
/**
* 提供外界来修改username的setter方法
* @param name
*/
public void setUsername(String name){
Username=name;
}
/**
* 提供外界来修改age信息的方法
* @param a
*/
public void setAge(int a) {
if (a<150 && a>0){
age=a;
}else {
System.out.println("请输入一个合法的age信息:"+a);
}
}
/**
* 提供给外界用来获取username属性的方法
* @return
*/
public String getUsername(){
return Username;
}
/**
* 提供给外界用来获取age属性的方法
* @return
*/
public int getAge(){
return age;
}
}
3.课堂案例
代码封装一个苹果手机类
package
com.bobo.oop;
/**
* @author xiaoye
* @date 2022/4/13 - 19:41
*/
/**
* 代码封装一个苹果手机类
*/
public class OOPDemo04 {
public static void main(String[]
args) {
Iphone phone =new Iphone();
phone.setBrand("iphone11");
phone.setColor("绿");
phone.setPrice(6666.6);
System.out.println(phone.getBrand()+"/t"
+phone.getColor()+"/t"
+phone.getPrice());
}
}
class Iphone{
private String brand;//品牌
private String color;//颜色
private double price;//价格
public void setBrand(String b){
brand=b;
}
public void setColor(String c){
color=c;
}
public void setPrice(double p){
price=p;
}
public String getBrand(){
return brand;
}
public String getColor(){
return color;
}
public double getPrice(){
return price;
}
}
4.关键字
this:代表当前类的对象引用,其实这个this和我们实现生活中的很多案例相似,比如:每个人都有一个名字,张三,李四,王五,代词,你,我,他等,this就相当于 我
为什么要使用this:
1. 成员变量和局部变量重名
2. 创建任意一个对象默认都会创建一个this的引用指向同一个堆区空间
3. This的设计就类似于现实生活中的代词 我的
4. 默认一个类的成员都会省略掉this关键字
5. 谁调用就是谁。This表示当前对象的引用
6. This只能够出现在类的内部。
this的本质就是一个对象,引用,实例,变量。只不过和创建的对象指向了同一堆区的空间,
使用this对堆区的空间做了修改一样会修改对象本身。
应用场景:
1.成员变量和局部变量同名的情况下
2.需要在类的内部访问本类的成员(成员变量和成员方法)
3.this访问本类的构造方法的时候(下节课就会介绍)
通过Eclipse工具快速封装相关的属性
5.构造方法
构造方法的作用:能够在对象创建之后对对象的成员变量快速的的赋值
普通方法的语法构造
{访问权限修饰符} 返回类型 方法者(参数列表){
方法体;
return 放回值;
}
构造方法的语法格式
{访问权限修饰符}类名 (参数列表){
方法体;
}
构造方法的特点:
1.构造方法没有返回值,连voidvoid关键字也没有
2.方法名必须和类名相同
3.方法体一般都是用来给成员变量赋值的
4.如果我们没有自己添加构造方法,系统会默认给我们提供一个无参的构造方法
5.如果自己添加了构造方法,那么会覆盖掉系统提供的默认的构造方法
6.构造方法可以重载
7.可以通过this关键字来实现构造器之间的调用,但是只能放置在构造方法的第一行
8.在书写任何一个类的时候,都加上无参构造方法是一个好的编程习惯
小结:一个最基本的类,书写应该具备的特点
1.成员变量
2.构造方法
1.无参构造方法
2.有参构造方法
3.成员方法
1.get方法
2.set方法
class StudentBean{
//成员变量
private int id;
private String name;
//构造方法
public StudentBean(int id, String name) {
this.id = id; this.name = name; }
//普通的Getter/Setter方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
6.面向对象综合练习
1.定义一个长方形类, 定义求周长和面积的方法,然后在定义一个测试类,进行测试。 Rectangle rec=new Rectangle(5, 3);
package com.bobo.oop2;
/**
* @author xiaoye
* @date 2022/4/16 - 10:12
*/
/**
* 定义一个长方形类,定义周长和面积的方法,然后在定义一个测试类,进行测试。
*/
public class oopdemo01 {
public static void main(String[] args) {
Rectangle rec=new Rectangle(5, 3);
System.out.println("长方形的周长是:"+rec.getPermater());
System.out.println("长方形的面积是:"+rec.getArea());
}
}
class Rectangle{
//定义属性 长度和宽度
private int lenght;
private int width;
public Rectangle() {
}
public Rectangle(int lenght, int width) {
this.lenght = lenght;
this.width = width;
}
/**
* 获取周长的方法
*/
public int getPermater(){
return this.lenght*2 + this.width*2;
}
/**
*获取面积的方法
* @return
*/
public int getArea(){
return this.lenght*this.width;
}
public int getLenght() {
return lenght;
}
public void setLenght(int lenght) {
this.lenght = lenght;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
}
2.封装一个学生类,有姓名,有年龄,有性别,有英语成绩,数学成绩,语文成绩,封装方法,求总分,平均分,以及打印学生的信息。
package com.bobo.oop2;
/**
* @author xiaoye
* @date 2022/4/16 - 11:00
*/
/**
* 封装一个学生类,有名字,年龄,性别,英语成绩,数学成绩,语文成绩,求总分,平均分,以及打印学生的信息
*/
public class oopdemo02 {
public static void main(String[] args) {
Student stu=new Student("张三",18,"男",88,92,96);
System.out.println(stu.getName()+"的总分:"+stu.getTotalScore());
System.out.println(stu.getName()+"平均分:"+stu.getAvgScore());
stu.printStudentInfo();
}
}
class Student{
//成员变量
private String name;
private int age;
private String gender;
private double englishScore;
private double mathScore;
private double chineseScore;
//空的构造器
public Student() {
}
//有参构造器
public Student(String name, int age, String gender, double englishScore, double mathScore, double chineseScore) {
this.name = name;
this.age = age;
this.gender = gender;
this.englishScore = englishScore;
this.mathScore = mathScore;
this.chineseScore = chineseScore;
}
/**
* 获取总分
* @return
*/
public double getTotalScore(){
return this.chineseScore+this.mathScore+this.englishScore;
}
/**
* 获取平均分
* @return
*/
public double getAvgScore(){
return this.getTotalScore()/3;
}
/**
* 打印学生信息
*/
public void printStudentInfo(){
System.out.println("name="+this.name+"/t age="+this.age
+"/t gender"+gender+"/t englishScore="+this.englishScore
+"/t mathScore="+this.mathScore+"/t chineseScore="+chineseScore);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public double getEnglishScore() {
return englishScore;
}
public void setEnglishScore(double englishScore) {
this.englishScore = englishScore;
}
public double getMathScore() {
return mathScore;
}
public void setMathScore(double mathScore) {
this.mathScore = mathScore;
}
public double getChineseScore() {
return chineseScore;
}
public void setChineseScore(double chineseScore) {
this.chineseScore = chineseScore;
}
}
3.定义一个点(Point)x y set get类用来表示二维空间中的点。要求如下
A 可以生成具有特定坐标的点对象
B 提供可以设置坐标的方法。
C 提供可以计算该点距离另一点距离的方法。
D 提供可以计算三个点构成图形的面积的方法。
面积可以使用海伦公式:边长分别为a.b.c p=(a+b+c)/2
s=Math.sqrt( p*(p-a)(p-b)(p-c))
package com.bobo.oop2;
/**
* @author xiaoye
* @date 2022/4/19 - 15:06
*/
public class oopdemo03 {
/**
* 3.定义一个“点”(Point)x y set get类用来表示二维空间的点。要求如下
* A 可以生成具有特定坐标的点对象。
* B 提供可以设置坐标的方法。
* C 提供可以计算该点距离另一点的距离方法。
* D 提供可以计算三个点构成图形的面积方法。
* @param args
*/
public static void main(String[] args) {
Point p1=new Point(1,1);
Point p2=new Point(2,1);
Point p3=new Point(2,2);
System.out.println("p1和p3之间的距离是:"+ p1.getDistance(p3));
System.out.println("p1.p2.p3三点之间构成的图案的面积是:"+p1.getArea(p1,p2,p3));
}
}
class Point{
private double x;
private double y;
public Point() {
}
//A 可以生成具有特定坐标的点对象。
public Point(double x, double y) {
this.x = x;
this.y = y;
}
/**
* 获取两个点之间的距离
* 计算当前点和另外一个点之间的距离
* @return
*/
public double getDistance(Point p){
double _x=this.x -p.getX();
double _y=this.y - p.getY();
Math.pow(_x,2);
//return Math.sqrt(_x*_x+_y*_y);
return Math.sqrt(Math.pow(_x,2)+Math.pow(_y,2));
}
/**
* 计算任意两个点之间的距离
* @param p1
* @param p2
* @return
*/
public double getDistance(Point p1,Point p2){
double _x=p1.x -p2.getX();
double _y=p1.y - p2.getY();
Math.pow(_x,2);
//return Math.sqrt(_x*_x+_y*_y);
return Math.sqrt(Math.pow(_x,2)+Math.pow(_y,2));
}
/**
* 提供可以计算三个点构成图形的面积的方法。
* 面积可以使用海伦公式;边长分别为a,b,c p=(a+b+c)/2
* s=Math.sqrt(P*(p-a)(p-b)(p-c))
* @return
*/
public double getArea(Point p1,Point p2,Point p3){
double a =getDistance(p1,p2);
double b=getDistance(p3,p2);
double c=getDistance(p1,p3);
double p=(a+b+c)/2;
return Math.sqrt(p*(p-a)*(p-b)*(p-c));
}
public double getY() {
return y;
}
public double getX() {
return x;
}
//B 提供可以设置坐标的方法。
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
}
7.static关键字
static修饰的变量我叫静态变量/共享变量/类变量
static的特点:
1.静态变量属于某个类,而不属于某个具体的对象
2.只有静态才能访问静态,非静态变量不能够出现在静态方法中
3.访问静态成员的方式
1.类名.成员变量
2.类名.成员方法
4.静态环境下不能出现this和super关键字
- static能够修饰的成员(成员变量,成员方法,修饰类 内部类)
- 我们开发自己的工具类的时候会经常用到static
8.代码块
使用"{}"包裹的就是代码块
8.1局部代码块
定义在类的局部位置,作用是:限定局部变量的作用域
public void show(){
{
//局部代码块
int i=10;
System.out.println(i);
}
{
//System.out.println(i);
}
System.out.println("name="+name+"country="+country);
}
8.2构造代码块
定义在类的成员变量的位置,用来抽取多个构造方法重复的代码块,做成员变量的初始化操作
会优先于构造方法执行
{
//构造代码块 执行顺序在构造方法之前执行
System.out.println("构造代码块...");
}
8.3静态代码块
static修饰的代码块就称为静态代码块
作用:一般用于初始化静态成员变量
静态代码块
只会执行一次,在类加载的时候执行
static {
//静态代码块
System.out.println("静态代码块执行了...");
country="中国";
}
这三者的执行顺序
静态代码块>构造代码块>构造方法
静态代码块只执行一次,在类加载的时候
构造代码块和构造方法在类对象创建的时候执行,可以执行很多次
9.package和import关键字
9.1为什么使用package
1.可以处理类重名的问题
2.方便管理数目众多的类
9.3包的语法格式
包(package)的本质就是文件夹
格式
package 包名;//包名表示的是当前这个类 所处的文件夹路径
有了这个路径我们就可以将当前类供其他类来使用
在使用其他类的功能的使用有几个注意点
1.在同一个包下的类可以直接使用
2.在Java中java.long包下面所以的类型可以直接使用。
- 除了以上两点其他类型的使用我们都必须通过impact关键字来导入才开始使用
9.3import的语法格式
impact语法格式
import 类的全路径;
包名:满足标识符的规则即可
注意事项:
1.同包下不需要导包
2. java.lang下面所有的类也不需要导包
2. 如果一个类没有包名,那么该类将不会被其他包所导入
2. 建议先创建包,在创建类
2. 包的声明必须出现在第一句,注释除外,package语句在一个java文件中只能出现一句
2. 我们需要使用到一个包下面的多个类型,那么这时候我们可以通过包名.*;的方式使用
2. 如果一个类文件需要使用到两个包下同名的类型,一个通过import来导入,两个通过代码中全路径指定的方式来现实
2. 在定义类的时候不要和系统名相同
package com.bobo.oop04;
import com.bobo.oop05.Student;
/*import com.bobo.oop05.Student;
import com.bobo.oop05.User;*/
import com.bobo.oop05.*;
/**
* @author xiaoye
* @date 2022/4/26 - 18:53
*/
public class oopdeam01 {
public static void main(String[] args) {
UserBean user=new UserBean();
user.run();
//java.long包的类型可以直接使用
String s="...";
// com.bobo.oop05.Student sut=new com.bobo.oop05.Student();
Student stu=new Student();
User u=new User();
// 我们需要使用到oop06下面的Student 类型
com.bobo.oop05.Student s2=new com.bobo.oop05.Student();
}
}
四、继承
1.继承的语法格式
格式
class 子类名称 extends父类名称{
}
被继承的这个类为父类,基类或者超类
继承的这个类为称为子类或者派生类
2.继承的案例
父类
package com.bobo.oop07;
/**
* @author xiaoye
* @date 2022/4/27 - 20:44
*/
/**
* 这是个Person类,抽取了Student、Doct、Police三个类的公共代码
*/
public class Person {
private String country;
public String name;
public int age;
public String gender;
public void sleep(){
System.out.println("sleep....");
}
}
Student .poilc.Doctor三个类
package com.bobo.oop07;
/**
* @author xiaoye
* @date 2022/4/27 - 19:38
*/
/**
* 这是一个学生类
* @author dpd
*/
public class Student extends Person{
public String stuNo; //学生编号
public void study(){
System.out.println("study....");
}
}
Poilc
package com.bobo.oop07;
/**
* @author xiaoye
* @date 2022/4/27 - 19:45
*/
/**
* 这是一个警察类
* @author dpb
*/
public class Police extends Student{
public String policeNo;//警员编号
/**
* 抓坏人的方法
*/
public void catchBadGuys(){
System.out.println("....");
}
}
Doctor
package com.bobo.oop07;
/**
* @author xiaoye
* @date 2022/4/27 - 19:51
*/
/**
* 这是一个医生类
* @author dpd
*/
public class Doctor extends Person {
public String doctorNum; //医生编号
public String department;//部门
public void savePeople(){
System.out.println("save...");
}
/**
* 代码优化快捷键ctrl+shift+f
* 这个快捷键会和搜狗输入法的快捷键冲突
*/
/** class Person {
public String name;
public int age;
public String gender;
public void sleep(){
System.out.println("sleep...");
}
}*/
}
3.继承的好处
1.简化了代码
2.提高了代码的可维护性
3.提高了扩展性
4.继承的缺点
开发设计思想:高内聚低耦合(尽量在一个类里面内聚,类和类之间的关系尽量保持独立)
继承后耦合性提高,牵一发动全身,这个缺点不能改进,在java中尽量不要使用继承
5.继承的注意事项
1.继承是对一批类的抽象,类是对一批对象的抽象
2.Java中只支持单继承,不支持多继承,但是支持多层继承
3.子类可以继承父类private修饰的属性和方法,但是不可见
4.子类不可以继承父类的构造方法
5.子类除了继承父类的属性和方法以外,还可以添加自己的属性和方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9TnZfIe8-1652267195238)(C:\Users\11640\Pictures\Saved Pictures\ji.png)]
6.这么使用继承
继承的本质是什么?–>简化代码
1.先写出所有的子类,观察子类共有的成员变量和成员方法
2.抽象出给共同点,书写出父类
3.让子类区继承父类,并把子类中的共有的属性删除
7.课堂案例
1.定义一个人类(姓名,性别,年龄,吃,睡),学生类继承人类(学号,班级,课程),老师类继承人类(工号,教龄,教书)
package com.bobo.oop08;
/**
* @author xiaoye
* @date 2022/4/28 - 14:44
*/
/**
* 1.定义一个人类(姓名,性别,年龄,吃,睡),学生类继承人类(学号,班级,课程),老师类继承人类(工号,教龄,教书)
*/
public class People {
public String name;
public int age;
public String gender;
public void eat(){
System.out.println("Person.eat()...");
}
public void sleep(){
System.out.println("Person.sleep()...");
}
}
package com.bobo.oop08;
/**
* @author xiaoye
* @date 2022/4/28 - 14:48
*/
/**
* 学生类继承人类(学号,班级,课程),
*/
public class Student extends People{
public String classes;
public String stuNo;
public Sting course;
}
}
package com.bobo.oop08;
/**
* @author xiaoye
* @date 2022/4/28 - 14:56
*/
/**
* 老师类继承人类(工号,教龄,教书)
*/
public class Teacher extends People{
public String workNum;
public String schoolAge;
public String course;
}
8.super关键字
super关键字可以理解为父类关键字,this关键字表示当前对象
当一个属性的使用没有添加this或者super关键字,那么它的查找顺序是 局部变量 ->成员变量->父类变量 如果还没有找到那么就会报编译异常
被this修饰的变量,如果本类的成员变量中没有找到,同样也会去父类中查找
被super修饰的变量,只会从父类中查找,如果父类中没有,而子类中存在,同样会报编译错误
super和this关键字访问成员的区别
成员变量
1.this成员变量
2 .super.成员变量 super是不能访问私有的成员变量
成员方法:
-
this.成员方法
-
super.成员方法
构造方法:
-
this.(参数列表)
-
super.(参数列表)
如何一个构造方法都默认的会在构造方法的第一句写上super();访问父类的无参构造方法
目的是初始化父类的成员变量
Constructor call must be the first statement in a construtor
super和this方法构造方法都必须出现在构造方法第一句。this和super在方法构造方法的时候,二者是不能共存
static静态的上下文都是不能出现this和super的
案例代码:
package oop01;
import java.awt.event.ActionListener;
import java.lang.reflect.Constructor;
import java.sql.Statement;
/**
* @author xiaoye
* @date 2022/4/28 - 20:35
*/
public class Son extends Father{
/**
* 在子类中定义了一个和父类中同名的属性
* 子类中定义的同名的属性会覆盖掉父类中的属性
*/
public int num=30;
public void show(){
//局部变量会覆盖掉成员变量
int num=40;
//输出局部变量
System.out.println("nwm:"+num);
//输出成员变量
System.out.println("nwm:"+this.num);
//输出父类的成员变量
System.out.println("num:"+super.num);
System.out.println(super.getAge());
eat();
}
public Son(){
super();//在构造方法中,默认都会添加语句Super(); 而且必须是第一行
//Constructor call must be the first Statement in a constructor
System.out.println("Son 子类构造器执行了....");
}
public Son(int nwm){
this();
//super(); 会在无参构造器中执行super();此处如果在执行一次就会出现两次初始化父类中成员变量的情况
}
}
package oop01;
/**
* @author xiaoye
* @date 2022/4/28 - 20:36
*/
public class Father {
public int num=10;
private int age;
public void eat(){
System.out.println("Father.eat...");
}
public Father(){
System.out.println("Father....构造器执行了");
}
public int getAge() {
return age;
}
}
package oop01;
import java.awt.*;
/**
* @author xiaoye
* @date 2022/4/28 - 20:43
*/
public class oopdemo01 {
public static void main(String[] args) {
Son son=new Son();
son.show();
}
}
9.访问权限修饰符
作用:表示被修饰的元素的访问权限
访问权限修饰符有四个:public protected 【default】private
访问权限修饰符可以修饰的元素:
1.类 只有public,adstract 和final能够修饰,或者不加【private和protected可以修饰内部类】
2.成员变量
3.成员方法
四个修饰符的特点
1. public修饰的成员对一切类可见
2. protected修饰的成员本包括下面都可见,不同包下只有子类可见
3 . default修饰的成员仅对空间下面可见
4. private修饰的成员仅对本类可见
Java中的封装就是通过访问权限修饰符来实现的
访问权限修饰符的宽严的关系
public>protected>default>private
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W0uyTs5F-1652267195238)(C:\Users\11640\Pictures\Saved Pictures\pu.png)]
10.方法的重写
如果父类继承的方法不能满足子类需求的情况下,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写,子类中出现了和父类一模一样的方法声明,,也称为方法的覆盖或者方法的重写。
方法重写的规则
- 方法名称相同
- 参数列表相同
- 返回值类型相同或者是其子类
- 访问权限修饰符不能严于父类
方法重写的注意事项:
1. 父类中的私有的方法不能重写的
1. 构造方法不能被重写
1. 子类重写父类方法时,访问权限不能更低
1. 重载和重写的区别
面试题:
重载和重写的区别
重载的定义:
- 同一个类中
- 方法名称相同
- 参数列表不同
- 和返回值及访问修饰符没有关系
位置 | 方法名 | 参数列表 | 返回值 | 访问权限修饰符 | |
---|---|---|---|---|---|
方法重写 | 子类 | 相同 | 相同 | 相同或者子类 | 不能严于父类 |
方法重载 | 同类 | 相同 | 不相同 | 没有关系 | 没有关系 |
12. final关键字在
final关键字是最终 的意思,可以修饰类,变量和方法
12.1修饰类
该类就不能被继承
12.2修饰变量
变量就会变为常量,只能赋值一次,之后就不能改变了 ,final修饰的变量称为常量,常量名我们都大写 ,常量一般我们会声明为static
成员变量:在定义的同时必须给出初始值
局部变量:可以在使之前赋值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5nmpng2P-1652267195239)(C:\Users\11640\Pictures\Saved Pictures\8.png)]
12.3修饰方法
final 修饰的方法,子类是不能重写该方法的!
Cannot override the final method form Person
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mWueZKfP-1652267195239)(C:\Users\11640\Pictures\Saved Pictures\9.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5JqB9LSW-1652267195239)(C:\Users\11640\Pictures\Saved Pictures\10.png)]
五、多态
1.现实生活中的多态
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SsEpdOww-1652267195240)(C:\Users\11640\Pictures\Saved Pictures\12.png)]
生活中的多态:同一个动作在不同情况下的不同的状态
2.Java中的多态
同一个引用类型,使用不同的实例而执行不同的操作,即父类引用指向了子类对象
多态的实现:
- 必须存在继承
- 必须存在重写
- 必须有父类引用指向子类对象 父类 fu=new子类();
案例:
package oop07;
import sun.applet.Main;
import java.net.SocketTimeoutException;
/**
* @author xiaoye
* @date 2022/5/6 - 20:19
*/
public class oopDemo01 {
/**
* 现实生活中的多态通过Java代码来实现
* Cut
* 理发师:剪头发
* 医生:动手术
* 演员:暂停3
*/
public static void main(String[] args) {
//将一个子类的实现赋值给了一个父类的引用
CutMan m1=new Barber();
CutMan m2=new Doctor();
CutMan m3=new Actor();
m1.cut();
m2.cut();
m3.cut();
}
}
class CutMan{
public void cut(){
System.out.println("我也不知道干嘛/...");
}
}
class Barber extends CutMan{
/**
* @Override 表示当前这个方法是一个重写的方法,
* 然后会按照重写的规则来校验是否满足
*/
@Override
public void cut(){
System.out.println("理发师:理发");
}
}
class Doctor extends CutMan{
@Override
public void cut(){
System.out.println("医生:动手术");
}
}
class Actor extends CutMan{
@Override
public void cut(){
System.out.println("演员:暂停");
}
}
代码的输出:
理发师:理发
医生:动手术
演员:暂停
3.多态访问成员的特点
在多态(父类引用指向子类的实现)的情况下,我们访问引用相关的成员(成员变量,成员方法,构造方法,静态方法)时的情况
父类类型 变量名-new子类名称();
3.1成员变量
在多态中,成员变量不存在覆盖的情况,在访问的时候是直接访问的父类中的属性(狐狸有九条命,但是能说动物有九条命嘛?)
编译看左边类,运行看左边类型
3.2成员方法
在多态中,因为方法存在重写(覆盖),所以在访问的时候执行的是子类中重写的方法
编译看左边,运行看左边
3.3构造方法
先执行父类的构造方法,可以帮助我们初始化父类的成员变量,然后执行子类的构造方法中其他的代码来实现子类成员变量的初始化。
3.4静态成员
多态中不会继承静态方法,因为静态方法是属于类的。所以在多态中我们调用静态方法那么执行的也是父类中的静态方法
编译看左边,运行也是看左边
4.多态的好处
多态的好处:
1. 简化代码
1. 提高了程序的扩展性
1. 提高了程序的可维护性
多态的应用:
1. 使用父类作为一个方法的形参,如果一个父类作为参数,那么我们可以传入父类对象,也可以传入对应的子类,这就是多态的常见应用
1. 使用父类作为一个方法的返回值,暂时先不讲,在还没结合抽象类和接口统一介绍
package oop07;
import oop04.Father;
import sun.applet.Main;
/**
* @author xiaoye
* @date 2022/5/7 - 14:10
*/
public class oopdemo02 {
private static Feeder feeder;
/**
* 设计原则
* 1.高内聚低耦合
* 2.对扩展开放,对修改关闭
* 党我们要去修改或者添加一个功能的时候,建议可以新增加代码,不要去修改原有的代码
* @param args
*/
public static void main(String[] args) {
Feeder feeder=new Feeder();
Panda p=new Panda();
Bamboo b=new Bamboo();
//feeder.feederPandaEatBamboo(p,b);
feeder .feeder(p,b);
Tiger t=new Tiger();
Meat m=new Meat();
// feeder.feederTigerEatMeat(t,m);
feeder .feeder(t,m);
Animal pig =new Pig();
Food fodder=new Fodder();
feeder .feeder(pig,fodder);
}
}
class Feeder{
/**
* 给熊猫喂竹子
*/
/**
public void feederPandaEatBamboo(Panda p,Bamboo b){
p.show();
b.show();
}
public void feederTigerEatMeat(Tiger t,Meat m){
t.show();
m.show();
}
*/
/**
* Animal a=new Pig();
* Food f=new Fodder();
* @param a
* @param f
*/
public void feeder(Animal a,Food f){
a.show();
f.show();
}
}
/**
* 动物类
*/
class Animal{
public void show(){
System.out.println("啥也不是...");
}
}
class Panda extends Animal{
@Override
public void show() {
System.out.println("熊猫");
}
}
class Tiger extends Animal{
@Override
public void show() {
System.out.println("老虎");
}
}
class Pig extends Animal{
@Override
public void show() {
System.out.println("猪");
}
}
/**
* 食物类
*/
class Food{
public void show(){
System.out.println("不知道什么食物");
}
}
//竹子类
class Bamboo extends Food {
@Override
public void show() {
System.out.println("竹子");
}
}
//肉
class Meat extends Food{
@Override
public void show() {
System.out.println("肉");
}
}
class Fodder extends Food{
@Override
public void show() {
System.out.println("饲料");
}
}
5.多态的缺点
在多态中如果我们想要调用子类特有的方法及属性值实现不了
多态中的类型转换
向上转型(自动转换)
格式:<父类型><引用变量名>=new<子类型>();
特点:
子类转为父类,父类的引用指向子类对象。自动进行类型转换
此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法
此时通过父类引用变量无法调用子类特有的属性和方法
向下转型(强制转换)
格式<子类型><引用变量名>=(<子类型>)<父类型的引用变量>;
特点:
父类转为子类,父类引用转为子类对象。强制类型转换
在向下转型的过程中,如果没有转换为真实子类类型,会出现类型转异常
public static void main(String[] args) {
Person p=new Stdent();
p.eat();
//在多态中如果我们想要调用子类特有的方法实现不了
/** Stdent s=new Stdent();
s.study();*/
//强制将一个父类转化为一个子类
Stdent s=(Stdent)p;
s.study();
doctor d=(doctor) p;
// d.study();
}
类型转换异常信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ujA41xin-1652267195240)(D:\新建文件夹 (2)]\QQ截图20220509210411.png)
6.instanceof关键字
测试它在左边的对象是否是它右边的类型的实例,返回boolean类型的数据
记住:instance of通常和向下转型(强制类型转换)
public static void main(String[] args) {
Person p=new Stdent();
p.eat();
//在多态中如果我们想要调用子类特有的方法实现不了
//我们强制类型转换之前最好做以下类型判断
/** Stdent s=new Stdent();
s.study();*/
//强制将一个父类转化为一个子类
if (p instanceof Stdent){
Stdent s=(Stdent)p;
s.study();
}else if (p instanceof doctor){
doctor d=(doctor) p;
// d.study();
}
}
规避 java.lang.ClassCastEexcepti异常
六、抽象类
1.抽象类的相关的概念
被abstract关键字修饰的类,就被称为抽象类
被abstract关键字修饰的方法被称为抽象方法。抽象方法是没有方法体的,抽象方法必须定义在抽象类中
Abstract methods do not specify a body
The abstract method eat in type Pet can only be defined by an abstract class
package oop09.oop08;
/**
* @author xiaoye
* @date 2022/5/10 - 14:32
*/
/**
* 宠物类
*/
public abstract class Pet {
String name;
/**
* 父类中的这个方法我们可以仅仅定义为一个声明,具体的实现交给子类去实现
*/
public abstract void ear();
}
格式:
//抽象类
abstract class 类名()
//抽象方法
abstract 返回值类型 方法名(参数列表)
2.抽象类的特点
1.抽象类和抽象方法一定要使用“abstract”关键字
2.抽象类中不一定有抽象方法
package oop09;
/**
* @author xiaoye
* @date 2022/5/10 - 15:08
*/
/**
* 抽象类中不一定有抽象方法
* 抽象方法一点要在抽象类中
*/
public abstract class Person {
}
3.没有抽象方法的抽象类的存在意义是什么? -->抽象类不能被实例化
不让外界创建对象
Connot instante the type Person
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b8SyBdxn-1652267195240)(D:\新建文件夹 (2)]\2.png)
4.抽象类虽然不能被实例化,但是我们可以用多态的思想来赋值
public class oopdemo01 {
public static void main(String[] args) {
// Person p=new Person() ;
Pet p1 =new Dog();
p1.ear();
}
}
5.作为抽象类的子类应该怎么办
父类
public abstract class Person {
public abstract void say();
}
子类有两个选择
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aS1Z6EXF-1652267195241)(D:\图片\3.png)]
-
把子类自身也变为抽象类
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HpP9NV7O-1652267195241)(D:\图片\1.png)]
-
实现父类的所有抽象方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qMi0DEr5-1652267195241)(D:\图片\4.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qhc8G6ou-1652267195242)(D:\图片\5.png)]