| |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| -> Java知识库 -> java面向对象和三大特征 -> 正文阅读 |
|
|
[Java知识库]java面向对象和三大特征 |
1.对象的特征(录屏day9、10)①特征(属性):一般为名词,代表对象有什么 ②行为:称为方法 一般为动词 代表对象能干什么 ③概念:实际上就是一个堆内存地址 2.类的定义2.1抽取:在形同或者类似的对象中,找出共同特征和行为 ①发现类:具有相同属性、行为的事物 ②找出类的属性 可以没有 ③找出类的行为 可以没有 和②得有一个 ④优化、继承、多态 2.2类的成员: 属性(字段)、成员变量、实例变量 类里的方法:通常都是非static的 类--内部类 后续学习 2.3类的创建:类名 对象名/变量名 = new 类名(); 2.4访问类中成员的语法:对象名.属性 对象名.方法名(); 案例1:创建对象 package com.qf.javasepro2105day9;
?
public class Demo1 {
?
1 public static void main(String[] args) {
// TODO Auto-generated method stub
//调用Dog里的eat()方法
//由于Dog类中的成员是非static修饰 所以不能用直接(名字+方法)访问
//需要将Dog类中的成员,放在堆内存中
//语法结构 类名 变量名 = new 类名();
2 Dog wangcai=new Dog(); ? //new一次堆内存 出来一个空间 通过地址访问
System.out.println(wangcai.age); ?//使用成员变量 结果0 ?
3 System.out.println(wangcai.name); //null
4 wangcai.eat(); ?//使用成员方法
5 System.out.println("--------------");
6 Dog huahua=new Dog();
7 huahua.name="花花"; ? ? ? ? ?
8 System.out.println(huahua.age); ?
9 System.out.println(huahua.name); ?//花花 我
10 huahua.eat();
}
?
}
案例1执行流程 栈内存 堆内存 1.main方法加载到栈最下边 2.创建第一个对象在main方法中, 出现name age 栈内存出现Dog wangcai 默认值 null 0 地址值001 指向 堆内存001的这个地址 3.输出 wangcai通过001 指向 001 4.调用者wangcai调用eat方法 在main方法上边 地址001 然后输出 方法执行结束从栈内存消失 6.创建第二个对象并使用 指向 huahua 地址002 堆内存002地址
8.输出 0 9.输出 花花 10.调用huahua 地址002 ? ? 输出 执行完毕方法从栈内存消失
? 案例1的调用 里边this. package com.qf.javasepro2105day9;
//1、发现类
public class Dog {
//2、发现类的属性、名词、对象有什么
//属性:用变量来表示、在类的内部,方法的外部的变量成为成员变量
//类的内部都可以使用成员变量 ? 局部变量在函数内有效、函数返回后失效
//毛色 成员变量
String clolr;
//昵称
String name;
//品种
String strain;
//年龄
int age;
//3、发现类的行为:动词,能做什么
//方法
//吃的方法 成员方法
public void eat() { ? //不写static
//局部变量可以和属性重名
String name="测试";
//输出语句中的name是局部变量name,不是实例变量的name
//如果同名时,默认使用局部变量
//如果就要使用属性,应该用 this.属性名 上边结果:
System.out.println("我是宠物:"+this.name+",正在啃骨头"); //我是宠物+上边name+正在...
System.out.println("我是宠物:"+name+",正在啃骨头"); //我是宠物+测试+正在啃骨头
}
//玩 ? 方法
public void play() {
System.out.println("在玩");
}
}
?
?
多个对象指向相同的对象内存图
? 图中 Student s2=s1; 把s1的值赋给s2; s2的地址和s1的地址001相等 都指向001 变动s2的值 s1也改变 0 案例2 对象数组,对象数组存的元素依然是内存地址 public class Demo8 {
public static void main(String[] args) {
Student jiaBao=new Student();
jiaBao.address="吉林省长春";
jiaBao.sex='男';
jiaBao.stuNo="qf001";
jiaBao.stuName="王家宝";
Student haoTian=new Student();
haoTian.address="辽宁省抚顺市";
haoTian.sex='男';
haoTian.stuNo="qf000";
haoTian.stuName="郑皓天";
Student zuEn=new Student();
zuEn.address="辽宁省丹东市";
zuEn.sex='女';
zuEn.stuNo="qf003";
zuEn.stuName="殷祖恩";
//自己声明的类 就是一种数据类型,student类型 属于引用类型
//多个学生,使用数字储存
//默认值 null
Student[] aryStu=new Student[5];
aryStu[0]=jiaBao;
aryStu[1]=haoTian;
aryStu[2]=zuEn;
for(int i=0;i<aryStu.length;i++) {
//System.out.println(aryStu[i]); //输出前三个地址和后两个里边的默认值 null
aryStu[i].sayHi();
}
}
}
?
案例2的方法public class Student {
//属性= 成员变量=实例变量=字段
String stuNo; //学号
String stuName; //姓名
char sex;//性别
String address;
//方法
public void sayHi() {
String stuName="dad111";
System.out.println("大家好,我叫"+this.stuName+",学号"+this.stuNo+"性别"+this.sex
+",住在"+address);
}
}
2.5实例变量与局部变量的区别
3.方法重载(录屏day11)3.1方法重载 ① 概念:在同一个类中,定义多个名称相同的方法,同名不同参 ② 前提:在同一个类中 ③ 主要点:方法名相同 参数不同:个数、类型(顺序) ④ 不看:与修饰符、返回值类型、参数名无关 好处:方便程序的记忆、调用 ⑤ 调用:根据方法名+参数决定调用哪一个重载的方法 案例3:方法重载的应用package com.qf.javasepro2105.day11;
?
public class OverLoadDemo {
//处理结果
public void doResult(int num) {
System.out.println("输出整数num:"+num);
}
public void doResult(String str) {
System.out.println("输出字符串str:"+str);
}
public void doResult(int num,String str ) {
System.out.println("num="+num+",str="+str);
}
public void doResult(String str,int num) {
//参数类型,参数顺序不同的重载
System.out.println("num="+num+",str="+str);
}
//参数名不同,不是重载
// public void doResult(String a,int b) {
//
// }
//不是方法重载,不看返回值类型
// public String doResult(String str,int num) {
// return "";
// }
//不是方法重载,不看访问修饰符
// private void doResult(String str,int num) {
//
// }
}
?
4.构造方法①概念:是一个特殊的方法,名字必须和类名相同,没有返回值,连void也没有 ②用途:1、创建对象时被使用 2、给属性赋值 ③调用:1、new的时候被调用 2、在子类的构造方法的第一条语句被调用 3、不能通过对象名或类名来调用 补充:java会默认每一个类,都去添加一个public 的无参数的构造方法,一旦程序员在类中添加了有参数构造方法,那么系统就不会为类添加public的无参的构造方法 经验:在编写有参构造方法的同时,一定要重载上无参的构造方法 案例4:构造方法的重载应用给属性赋值的方式有三种: 1、对象.属性名=值 2、通过构造方法给属性赋值 利用实参和形参一一对应的特点,必须要传递指定个数、类型、顺序相同的参数 3、封装后,setXXX() 对给定的值的范围进行判断 package com.qf.javasepro2105.day11;
?
public class Cat {
String name;
int age;
//构造方法 ?
public Cat() {
//重载无参的构造方法
System.out.println("我是Cat类的构造方法");
}
public Cat(String name) {
this.name=name; //局部变量给成员变量
}
public Cat(String name,int age) {
this.name=name; ? //形参name赋值实参name
this.age=age;
}
public void sayHi() {
System.out.println("我是宠物"+this.name+"今年"
+this.age+"岁!");
}
}
?
package com.qf.javasepro2105.day11;
?
public class Demo4 {
?
public static void main(String[] args) {
// TODO Auto-generated method stub
Cat mimi = new Cat(); //new一次 堆内存出来一个空间,通过地址访问
mimi.sayHi(); ?//mimi调用sayHi方法
Cat hihi = new Cat("哈哈"); //名字赋值
hihi.age=1; ?//把 hihi的年龄赋值1 ? 第一种赋值方式
hihi.sayHi(); //hihi使用sayHi方法
Cat lulu =new Cat("露露",5); //构造方法赋值,形参实参一一对应
lulu.sayHi(); ?//lulu使用sayHi方法
}
?
}
?
5.this关键字this.当前对象,使用哪个对象来访问属性,this存放就是哪个对象的内存地址 ①案例5:调用属性或方法:this第一种用法package com.qf.javasepro2105.day11;
?
public class Cat {
String name;
int age;
//构造方法 ?
public Cat() {
//重载无参的构造方法
System.out.println("我是Cat类的构造方法");
}
public Cat(String name) {
this.name=name; //局部变量给成员变量
}
public Cat(String name,int age) {
this.name=name; ? //形参name赋值实参name
this.age=age;
}
//在类中,一个方法可以调用另一个方法
public void sayHi() {
System.out.println("我是宠物"+this.name+"今年"
+this.age+"岁!");
this.test();//二者选其一就行 当方法名比较长 用this.后边可以自动出来
test(); ? ? //二者选其一就行 当方法名比较长 用this.后边可以自动出来
}
public void test() {
System.out.println("学习this");
}
}
?
②案例6:在一个构造方法中,通过this调用另一个构造方法,必须在本方法中是第一条有效语句public class Cat {
String name;
int age;
//构造方法 ?
public Cat() {
//重载无参的构造方法
System.out.println("我是Cat类的构造方法");
}
public Cat(String name) {
this.name=name; //局部变量给成员变量
}
public Cat(String name,int age) {
this(name); //在两个参数的构造方法中,利用this调用另外一个方法
this.age=age;//调用上边一个参数name的方法
? }
}
6.面向对象三大特性6.1封装 ①使用封装意义:在给属性赋值时,符合语法要求,但是不符合实际意义 ②封装的实现步骤: 1.将属性私有 使用private 修饰 private int age; 2.通过setXXX()进行私有属性赋值 通过getXXX()进行私有属性的取值 //赋值方法
public void setAge(int age){
this.age=age;
}
//获取值的方法
public int getAge(){
return this.age;
}
3.在setXXX()方法中,对值的有效范围进行判断 //赋值方法
public void setAge(int age){
this.age=age;
}
//获取值的方法
public int getAge(){
return this.age;
}
在类的外部,访问私有属性时,会报错:The field Dog.age is not visible ③封装的概念:将类的细节(属性)隐藏在类的内部(private),通过对外的公共接口(public修饰的方法)进行访问,确保了类的安全。 6.2继承 ①继承的意义:代码复用 extends ②继承的概念:描述的类和类之间的一种关系,通过这种关系,子类就可以复用父类中可以访问的成员,达到代码复用的目的 ③父类子类关系: 父类:存放共同成员 超类(super)、基类(base) 子类:存放独有成员 is-a 关系:是一个 用来判断继承是否合理 子类 extends 父类 子类 is a 父类 ④继承的特点: 1、传递性 子类继承父类,父类又继承父类,那么子类会间接继承“爷爷类”里的成员 Pig类继承了Pet类,Pet继承了Object类,那么Pig类间接继承了Object类 每一个类都默认继承一个类,Object类 2、类单继承:子类只能直接继承一个父类 ⑤继承的本质: Peguin qq= new Peguin(); qq.setName(""); 创建对象的顺序; Peguin qq =new Peguin();
? 案例7:使用继承①、新建一个类,把重复的代码放入此类中(父类) package com.qf.javasepro2105.day11;
//pet类 pet类 ? pet类 ? pet类 ? pet类 ? pet类 ? pet类
public class Pet {
private String name;
private int age;
public Pet(){
super();
System.out.println("执行了父类的构造方法");
}
public Pet(String name,int age){
super();
this.name=name;
this.age=age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) { ?//确定年龄范围
if(age>0 || age<30) { ? ? //set方法的范围有效值
this.age = age;
}else {
this.age=0;
}
}
public int getAge() {
return age;
}
}
?
②让代码重复的类 继承 新建的类 Peguin类 package com.qf.javasepro2105.day11;
?
public class Peguin extends Pet {
public Peguin(){
//隐式调用父类构造方法
super(); ?//隐式调用父类无参的构造方法
System.out.println("执行了Peguin类的构造方法");
}
//子类有参构造方法
public Peguin(String name,int age,String addr){
//调用父类有参构造方法
super(name,age);
this.addr=addr;
}
private String addr;
public void sayHi(){
System.out.println("大家好,我是一只住在"+this.addr+"的企鹅,我的名字是"+
this.getName() +",今年"+this.getAge()+"岁!");
}
?
public String getAddr() {
return addr;
}
?
public void setAddr(String addr) {
this.addr = addr;
}
public void test(){
//this.name=""; 私有成员没有继承下来,不能访问
this.num=10; ?//子类和父类在同一包内,因此可以访问父类中默认成员
this.str="受保护成员";
this.jiabao="子类可以访问父类中的public";
}
}
?
pig类 package com.qf.javasepro2105.day11;
//特有种类
public class Pig extends Pet{
//共同代码放到Pet中 ?
private String strain;
public void setStrain(String strain) {
this.strain = strain;
}
public String getStrain() {
return strain;
}
public void sayHi(){
System.out.println("大家好!我是一只"+this.strain+"猪,我的昵称是:"+this.getName()+
",今年"+this.getAge()+"岁!");
}
}
子类继承了父类的哪些成员? 私有成员,使用private修饰的成员,子类没有继承下来,因此不能访问 默认访问修饰符,没有任何访问修饰符就是默认访问修饰符,是包内可见,只要在同一包内即可访问 protected 受保护的,包内可见,子类可见 当前类(父类) 同包子类 同包其他类 不同包子类 不同包其他类 private √ × × × × 默认 √ √ √ × × protected √ √ √ √ × public √ √ √ √ √ 【结论】子类没有继承父类的private成员,当不在同一个包时父类的默认成员 作业: 1、梳理好知识点,弄清楚知识 2、做课堂案例 3、Question7 Question8 宠物管理系统: 1、添加宠物 2、显示宠物信息 3、修改宠物 4、删除宠物 |
|
|
|
|
| 上一篇文章 下一篇文章 查看所有文章 |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| 360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年10日历 | -2025/10/23 16:03:20- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |