java从入门到精通OOP
Posted cgblpx皮皮霞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java从入门到精通OOP相关的知识,希望对你有一定的参考价值。
文章目录
1 面向对象1
1.1 面向对象
1.1.1 概念
所谓的面向对象是一种编程思想,通过这种思想可以把生活中的复杂事情变得简单化,从原来的执行者变成了指挥者,面向对象是基于面向过程而言的。
我们经常说的面向对象的编程实现(OOP,Object Oriented Programming)
面向过程强调的是过程,例如:
1、打开冰箱 2、把大象放进去 3、关上冰箱
面向对象强调结果,例如:
1、 饿了,去平台点餐,这个动作就是面向对象。你没有去市场买菜洗菜做饭。。。只要有app就可以了。
2、 衣服脏了,直接甩给女票去处理等着穿干净的就可以了。你没有关注中间的过程。。只要找好对象就可以了。
3、面试官问什么是面向对象?你答万物皆对象!!不建议因为你还没到这个深度,最好举例。就像是,你说空即是色色即是空—信你个鬼。
1.1.2 三大特征
1、 封装性,把相关的数据封装成一个“类”组件
2、 继承性,是子类自动共享父类属性和方法,这是类之间的一种关系
3、 多态,增强软件的灵活性和重用性
1.2 类和对象
1.2 类和对象
1.2.1 类
1、 Java语言最基本单位就是类,类似于类型。
2、 类是一类事物的抽象。
3、 可以理解为模板或者设计图纸。
1.2.2 对象
每个对象具有三个特点:对象的状态,对象的行为和对象的标识。
1、 对象的状态用来描述对象的基本特征。
2、 对象的行为用来描述对象的功能。
3、 对象的标识是指对象在内存中都有一个唯一的地址用来和其他对象区分开来。
4、 类是一类事物的抽象,对象是具体的实现。
1.2.3 类和对象的关系
1、 计算机语言是用来描述现实世界事物的。属性+行为
2、 那怎么通过java语言描述呢?通过类来描述事物,把事物的属性当做成员变量,把行为当做成员方法。
分析手机事物:
属性:颜色,尺寸,品牌,价格。。。
方法:打电话,发短信,听音乐。。。。
类:手机类,抽取相同的属性和行为
对象:可以按照模板生产很多个手机,比如1号手机对象,包含特有的成员变量和成员方法
1.3 类和对象的创建和使用
1.3.1 练习1:类的创建使用
通过class关键字创建类,通过new关键字创建对象。
package day000000;
public class Test1
public static void main(String[] args)
//p是引用对象,持有了对于Person对象的地址值的引用
//此时的p,含有属性,但都是默认值
Person p = new Person();
//设置属性值
p.name="lisi";
p.age=20;
//调用方法
p.eat();
p.sleep();
class Person
//属性--成员变量
String name;
int age;
//行为--方法
void eat()
System.out.println("吃饭饭");
void sleep()
System.out.println("睡觉觉");
1.3.2 对象在内存中的存储
Java把内存分成5大区域,我们重点关注栈和堆。
1、 一般来讲局部变量存在栈中,方法执行完毕内存就被释放
2、 对象(new出来的东西)存在堆中,对象不再被使用时,内存才会被释放
3、 每个堆内存的元素都有地址值
4、 对象中的属性都是有默认值的
1.3.3 单一对象内存图
Person p = new Person();
1、 在栈内存中,创建一个引用变量p,持有对象的地址值
2、 在堆内存中,创建Person对象,并且开辟变量的空间,完成初始化
3、 给堆内存中的元素,分配一个唯一标志,地址值。交给p去保存。
4、 p.name=”lisi”;p.age=20;就去堆内存中找唯一的地址值,找到Person对象,并对其属性进行修改赋值。
5、 p.eat();就去堆内存中找唯一的地址值,找到Person对象,执行Person对象的方法。
1.3.4 练习2:创建多个类
package day000000;
public class Test1
public static void main(String[] args)
//p是引用对象,持有了对于Person对象的地址值的引用
//此时的p,含有属性,但都是默认值
Person p = new Person();
//设置属性值
p.name="lisi";
p.age=20;
//创建p2
Person p2=new Person();
p2.name="zhangsan";
p2.age=10;
class Person
//属性--成员变量
String name;
int age;
//行为--方法
void eat()
System.out.println("吃饭饭");
void sleep()
System.out.println("睡觉觉");
1.3.5 多对象内存图
1、 变量p和变量p1不是一片空间,p1需要开辟新的空间
2、 Person p1=new Person,这时只要有new,就会新开辟空间在堆内存中存入对象。
1.4 封装
1.4.1 概述
封装是指隐藏对象的属性和实现细节,仅仅对外提供公共的访问方式。
好处:
1、 提高安全性
2、 提高重用性
案例:
1、 类
2、 方法
1.4.2 private关键字
是一个权限修饰符,用于修饰成员变量和成员函数,被私有化的成员只能在本类中访问。
想要修改只能,对外提供公共的,get和set方法。
1.4.3 练习1:封装学生
先用不同的变量名,不要出现this
package day006;
public class Student
//String name;
//把属性隐藏起来
private String name;
//提供公共的访问方法
//设置公共的赋值方法
public void setName(String n)
name=n;
//设置公共的取值方法
public String getName()
return name;
int age;
class StDemo
public static void main(String[] args)
Student s = new Student();
//不能访问私有的
//s.name="zhangsan";
//System.out.println(s.name);s
//利用setXxx()给属性赋值
s.setName("zhangsan");
//利用getXxx()给属性取值
System.out.println(s.getName());
1.5 拓展
1.5.1 创建Teacher类,并创建Teacher对象测试
老师事物:设置特性和功能
特征:姓名、年龄、住址
功能:讲课
测试:
创建Teacher对象
调用老师的属性和功能
修改老师的属性
1.5.2 编写汽车类并画内存图
属性:颜色,型号,品牌,价格
行为:开,飞。。。
汽车对象的创建和使用
1.5.3 创建对象的流程
Person p = new Person();//短短这行代码发生了很多事情
- 把Person.class文件加载进内存
- 在栈内存中,开辟空间,存放变量p
- 在堆内存中,开辟空间,存放Person对象
- 对成员变量进行默认的初始化
- 对成员变量进行显示初始化
- 执行构造方法(如果有构造代码块,就先执行构造代码块再执行构造方法)
- 堆内存完成
- 把堆内存的地址值赋值给变量p ,p就是一个引用变量,引用了Person对象的地址值
1.5.4 匿名对象
没有名字的对象,是对象的简化表示形式。
使用场景:
1、 当被调用的对象只调用一次时(多次会创建多个对象浪费内存)
Demo d = new Demo();
d.sleep();
d.game();
//这个d就是对象的名字。
也可以写成:
new Demo().show();//创建了一个对象调方法
new Demo().game();//又创建了一个对象调方法
2 面向对象2
2.1 构造方法
2.1.1 概念
构造方法是一种特殊的方法,它是一个与类同名且返回值类型为同名类类型的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的创建或者对象的初始化。当类实例化一个对象时会自动调用构造方法。
构造方法和其他方法一样也可以重载。
2.1.2 形式
可以无参也可以有参
修饰符 类名(【参数】)
代码……
2.1.3 练习1:构造方法创建对象
创建对象时的两种方
package day006;
public class Test2_构造方法
String name;
//当存在一个含参的构造方法时,无参构造将不再自动生成...
//public Test2_构造方法()
//含参构造
public Test2_构造方法(String n)
name=n;
void eat()
System.out.println("Test2_构造方法.eat()");
class tt
public static void main(String[] args)
//注释掉无参的构造也可以运行,说明系统会自动提供一个无参的构造方法
Test2_构造方法 t2 = new Test2_构造方法();
t2.eat();
//t是引用变量,引用的是对象的地址值。
//根据地址值找到对象,并获取对象的数据
Test2_构造方法 t = new Test2_构造方法("张三");
System.out.println(t.name);
2.1.4 练习2:构造方法赋值
package day006;
public class Test3_成员变量赋值
String name;
int age;
//赋值方式1:通过含参构造方法赋值
public Test3_成员变量赋值(String name,int age)
this.name=name;
this.age=age;
//赋值方式2:通过setXxx()方法赋值
public void setName(String name)
this.name=name;
public void setAge(int age)
this.age=age;
class Test3Demo
public static void main(String[] args)
//赋值方式1:通过无参构造方法赋值
Test3_成员变量赋值 t1= new Test3_成员变量赋值();
System.out.println(t1.name);
System.out.println(t1.age);
//赋值方式1.1:通过含参构造方法赋值
Test3_成员变量赋值 t2= new Test3_成员变量赋值("zhangsan",30);
System.out.println(t2.name);
System.out.println(t2.age);
//赋值方式2:通过setXxx()方法赋值
Test3_成员变量赋值 t3= new Test3_成员变量赋值();
t3.setName("rose");
t3.setAge(25);
System.out.println(t3.name);
System.out.println(t3.age);
2.2 构造代码块和局部代码块
2.2.1 构造代码块
1、 在类的内部,方法外部,的代码块。
2、 通常用于抽取构造方法中的共性代码。
3、 每次调用构造方法前都会调用构造代码块
4、 优先于构造方法加载
class c
String country;
country="中国";
public c()
System.out.println("1号选手,来自"+country);
public c(int a)
System.out.println("2号选手,也来自"+country);
2.2.2 局部代码块
1、 在方法里面的代码块
2、 通常用于控制变量的作用范围,出了括号就失效
3、 变量的范围越小越好,成员变量会有线程安全问题
4、 总结:执行顺序:
构造代码块是最优先的,局部代码块顺序执行
2.2.3 练习1:代码块加载顺序
package day99999;
public class TT
public static void main(String[] args)
Student s = new Student();
s.init();
class Student
System.out.println("构造代码块1");
public void init()
System.out.println("局部代码块");
System.out.println("构造代码块2");
2.3 this关键字
2.3.1 概念
this代表本类对象的一个引用对象。
构造函数中,this()必须放在第一行。
2.3.2 形式
name=name;
age=age;
其实是想把Student类的局部变量name的值赋值给成员变量,相当于你想操作是这样的:
//Student.name=name;
但是你不能直接写类名,这时候就用代表本类的对象this来完成。代码变成了:
this.name=name;
2.3.3 练习1:当变量名相同时
当局部变量和成员变量同名时,用于区分。
如果附近有同名变量,会遵从变量的就近原则,那么怎么调用成员变量呢?
package day99999;
public class T
public static void main(String[] args)
Animal a = new Animal();
a.run("大黄");
System.out.println(a.name);
class Animal
String name;
/*
//当局部变量的名字和成员变量不一样时简单,拿着局部变量的值直接给成员变量赋值就行了
public void run(String n)
name=n;
*/
//问题来了,当局部变量和成员变量同名时呢??
public void run(String name)
//name=name;//变量的就近使用原则,这样用的都是最近的也就是一直在用局部变量的
this.name=name;//this调用成员变量
2.3.4 练习2:构造方法间的调用
package day99999;
public class T
public static void main(String[] args)
Animal a = new Animal();
// Animal a2 = new Animal("旺财");
class Animal
public Animal()
this("来福");//调用本类中的含参构造
System.out.println(name);
public Animal(String name)
System.out.println(name);
2.4 继承
2.4.1 概念
继承是面向对象最显著的一个特性。
继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类/超类/基类。
这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。
提高复用性:只要继承父类,就能有一样的功能
class A extends c //原来的eat()拿走了
class B extends c //原来的eat()拿走了
class c
public void eat()
syso("eat");
2.4.2 特点
1、 使用extends关键字
2、 相当于子类把父类的功能复制了一份
3、 java只支持单继承
4、 继承可以传递(爷爷,儿子,孙子的关系)
5、 不能继承父类的私有成员
6、 继承多用于功能的修改,子类可以拥有父类的功能的同时,进行功能拓展
7、 像是is a 的关系
2.4.3 入门案例
package day99999;
public class TTT
public static void main(String[] args)
Zi zi = new Zi();
zi.speak();
System.out.println(zi.skin);
System.out.println(zi.addr);
class Fu
String skin="黄种人";
String addr="大成都";
public void speak()
System.out.println("Fu...speak()");
//通过extends和父类发生继承关系
//所有父类的功能,子类都可以继承过来,注意不能是private的
class Zi extends Fu
//什么都不写,能不能把父亲的内容复制一份出来
2.5 super关键字
1、 通过super关键字可以使用父类的内容
2、 super代表父类的一个引用对象
3、 如果用,必须出现在调用位置的第一行
2.6 方法的重写
1、 继承后,子类就拥有了父类的功能
2、 那么在子类中,可以添加子类特有的功能也可以修改父类的原有功能
3、 子类中方法签名与父类完全一样(包括方法的返回值,方法名和参数列表,完全一致)时,会发生覆盖/复写操作,相当于修改功能
注意:
1、父类中的私有方法不能被重写
2、子类重写父类方法时,修饰符要大于等于父类修饰符的权限
2.7 继承中的用法
2.7.1 成员变量的使用
局部的,成员的,父类的。
package day000;
public class Test2_LeiVariable
public static void main(String[] args)
Sub2 s= new Sub2();
s.show();
class Fu2
int num=20;
class Sub2 extends Fu2
int num;
public void show()
int num=9;
System.out.println(num);//变量的就近原则
System.out.println(this.num);//调用本类的成员变量,相当于Sub2.num
System.out.println(super.num);//调用父类的成员变量
2.7.2 成员方法的使用
继承方法,特有方法,重写方法
JAVA入门到精通-第38讲-线程-坦克大战6