一、什么是面向对象?
是一种编程思想,符合人的生活习惯,自己不想做的或者不会做的事情让别人去做好,自己直接使用做好的结果(懒人思想)---java
生活实例:饿了想吃饭,直接让爸妈做好或者让厨师做好
二、什么是面向过程?
做某件事情的每一个步骤都需要自己完成(亲力亲为)---c语言/c++
生活实例:买菜,洗菜,炒菜
三、什么是对象?
实实在在存在的事物就叫做对象(一句话概括--万物皆对象)
四、如何去区分这些对象
1.通过静态属性(属性/特征)---以后的学习统称为属性
例如:一个人 |属性: |性别 |名字 |年龄 |体重
| 属性值: |男 |张三 |18岁 |60kg
我们仅仅通过属性可以区分对象吗??
例如我有一台洗衣机和冰箱,如果我直接给出长100cm,宽50cm,白色。我们能够分辨的出是洗衣机还是冰箱吗??当然不能,但是如果我们给出一个“洗衣”/“冷冻”,是不是就可以区分冰箱和电视机了
2.那么洗衣和冰冻是什么呢??--动态属性(行为/功能/方法/函数)---以后的学习统称为方法
例如:我给出一辆车 |属性: |品牌 |价格 |颜色 |时速
| 属性值: |奔驰 |150万 |黑色 |200km/h
|行为: 加速、减速、刹车
那么我们是不是就可以从属性和行为就可以识别这辆车了!!
五、什么是类?
是所有的同种对象的集合的总称---人类/狗类/猫类...
那么在生活中是先有类还是先有对象??
解释:生活中,我们先有对象再有类这样的称呼
那么在程序中是先有类还有先有对象??
解释:程序中,我们是先有类,然后再有对象的
步骤:我们要实现这个对象,就必须先要创建一个类,然后通过这个类生成该类的一个对象
六、如何去实现面向对象?
第一步:创建一个类文件People.java(以人类为例)
package com.bianyiit.cast;
//类名是大驼峰命名法:每个单词的首字母都要大写
public class People { //类文件,不需要执行的,所以不需要写主方法
//作用:用来描述具体的对象用的(属性)
String name; //名字
char sex; //性别
int age; //年龄
double height; //身高
double weight; //体重
//吃饭的方法eat() --这里参考主方法写,但是先去掉static
public void eat(){
System.out.println("吃饭");
}
//打印姓名+性别+年龄+身高+体重的print()方法
public void print(){
System.out.println("name:"+name+"\n"+"sex:"+sex+"\n"+"age:"+age+"\n"+"height:"+height+"\n"+"weight:"+weight);
}
}
第二步:创建一个测试类文件(需要执行)
package com.bianyiit.cast;
public class PeopleTest {
public static void main(String[] args) { //创建一个测试类文件 这里一定要把主方法写上
//作用:用来生成类文件的对象用的
//书写格式:类名 对象名=new 类名();
People p1=new People();
//通过(对象名.属性=属性值)调用类中的属性并赋值
p1.name="张三";
p1.sex='男';
p1.age=18;
p1.height=175;
p1.weight=100;
//通过(对象名.方法)调用类中的方法
p1.print();
p1.eat();
}
}
//输出结果:
name:张三
sex:男
age:18
height:175.0
weight:100.0
吃饭
注意:成员变量有初始化值,而普通变量是没有初始化值的
七、类和对象在内存中是如何存在的?
栈内存:用来加载方法和局部变量用的
堆内存:用来加载new出来的东西和成员变量以及赋的值
方法区:类文件加载时生成的.class文件
八、对象调用属性进行随意的赋值(可能会出错),应该如何避免??
//假如我们给age赋值为-18岁,但是也能够输出打印出来,但是实际开发过程中不能这样去做,所以我们应该想办法去避免直接这样赋值
p1.age=-18;
//实际开发中如何解决这个问题呢??
第一步:将属性私有化 private 用private修饰属性
private String name; //名字
private char sex; //性别
private int age; //年龄
private double height; //身高
private double weight; //体重
第二步:Java给我们提供了一个很强大的功能,可以通过setxxx()和getxxx()对属性进行赋值和取值
//例如我们为年龄设置一个setAge()方法--有参无法的方法,用来判读并赋值
public void setAge(int a){
if(a>0&&a<=120){
age=a;
}else{
System.out.println("年龄不符合生活逻辑");
}
}
//我们为年龄设置一个getAge()方法--无参有返的方法,用来取值
public int getAge(){
return age;
}
//然后我们在测试类文件中通过如下方式给age赋一个负数值并取值
p1.setAge(-18);
int age=p1.getAge();
System.out.println(age);
//运行结果:
年龄不符合生活逻辑
0
//如果我们在测试类文件中通过如下方式给age赋一个正常值并取值
p1.setAge(18);
int age=p1.getAge();
System.out.println(age);
//运行结果:
18
这样做之后就能够避免对象调用属性进行随意的赋值了!!
总结:set和get方法对属性进行了封装,setXxx()设置属性值,getXxx()获取属性值
九、使用Alt+Insert直接快速生成set和get方法,Ctrl+A全选,然后点击OK
十、this关键字
总结:当局部变量和成员变量同名时,JVM就无法正确的去识别,这时我们可以通过this关键字去区分成员变量和局部变量,this---当前对象的引用
十一、局部变量和成员变量的区别
package com.bianyiit.cast;
public class JuBu_ChengYuan {
String name="王健林"; //成员变量,类里面,方法外面
public void print(){
String name="王思聪"; //局部变量
System.out.println(name); //--就近原则 //这个name是输出王健林还是王思聪??
System.out.println(this.name); //打印成员变量 //这个name是输出王健林还是王思聪??
}
public void show(){
System.out.println(name); //这个name是输出王健林还是王思聪??
}
public static void main(String[] args) {
JuBu_ChengYuan a=new JuBu_ChengYuan();
a.print();
a.show();
}
}
//输出结果:
王思聪
王健林
王健林
总结:1.位置--成员变量在类中,方法外,而局部变量在方法声明上或者方法中,也就是参数中
2.如果类中成员变量和局部变量同名,可以使用this关键字去区分
3.成员变量有默认值,而局部变量是没有默认值的,必须先赋值再使用
4.成员变量在整个类中都有效,而局部变量只有在方法中的{}中有效,出了{}就用不了局部变量了
十二、内存泄漏和JVM回收机制
//1.如果我们给对象名赋值为null,会出现什么结果??
//Student.java
package com.bianyiit.cast;
public class Student {
private String name;
public void setName(String name){
if(name.equals("张三")){
this.name=name;
}else{
System.out.println("名字出现逻辑错误,只能叫张三,不能叫李四!!");
}
}
public String getName(){
return name;
}
}
//StudentTest.java
package com.bianyiit.cast;
public class StudentTest {
public static void main(String[] args) {
Student s1=new Student();
s1=null; //如果直接给对象赋值为null,会出现什么结果??
}
}
//输出结果:空指针异常
Exception in thread "main" java.lang.NullPointerException
at com.bianyiit.cast.StudentTest.main(StudentTest.java:8)
//2.如果我们直接输出s1会出现什么结果??
//StudentTest.java
package com.bianyiit.cast;
public class StudentTest {
public static void main(String[] args) {
Student s1=new Student();
System.out.println(s1); //如果直接输出s1,会出现什么结果??
}
}
//输出结果:
com.bianyiit.cast.Student@1b6d3586---一串地址值
//解释:当我们给对象名赋值为null时,栈中的Student s1就不能够通过地址值直接找到堆中的new Student();了
//那么问题来了,堆里面的那些东西是否永久停留在堆里面??
那么问题来了,堆里面的那些东西是否永久停留在堆里面??
堆内存泄漏:对象的引用找不到具体的对象了,对象会不会永远存在于堆中呢??肯定不会,没有对象引用的这些对象会被垃圾回收器自动去回收,可能是1s,2s,0.5h...
//如果我们直接输出s1.toString()会出现什么结果??
//StudentTest.java
package com.bianyiit.cast;
public class StudentTest {
public static void main(String[] args) {
Student s1=new Student();
System.out.println(s1.toString()); //如果直接输出s1.toString(),会出现什么结果??
}
}
//输出结果:
com.bianyiit.cast.Student@1b6d3586---同样是一串地址值
直接输出对象名相当于是对象名.toString()---调用的是object里面的toString()方法
object是所有类的根类,object里面的toString()打印的是对象的地址值
为了避免输出的是地址值,我们可以在自定义类中去重写object里面的toString(),满足我们自己的需求
//自定义toString()的方法--1.可以避免输出的是地址值,2.我们不用再定义一个print()方法去显示成员变量的值了
public String toString(){
System.out.println("name:"+name+"\n"+"age:"+age+"\n"+"className:"+className);
}
十三、匿名对象
//Student.java
package com.bianyiit.cast;
public class Student {
private String name;
public void setName(String name){
if(name.equals("张三")){
this.name=name;
}else{
System.out.println("名字出现逻辑错误,只能叫张三,不能叫李四!!");
}
}
public String getName(){
return name;
}
public void run(){
System.out.println(name+"正在跑步中..");
}
}
//StudentTest.java
package com.bianyiit.cast;
public class StudentTest {
public static void main(String[] args) {
//Student s1=new Student();
new Student().name=18; //使用匿名对象进行赋值
new Student().run();
}
}
//输出结果:
null
//这里使用匿名对象时,在堆内存中创建的是两个不同的对象,并不是同一个对象在操作
图解:
匿名对象建议--当对象只需要使用一次的时候,除此之外,匿名对象还可以当做参数的传递。
课后作业
ZhaZhiJi.java
package com.homework;
/*1).写一个榨汁机类,属性: 价格,品牌;
方法:
(一)写榨汁机通电的方法,要求输出“正在通电”,没有返回
(二)榨汁的方法: 传入不同的水果,就得到不同的果汁,(如: 传入西瓜得到西瓜汁)*/
public class ZhaZhiJi {
int price; //价格
String brand; //品牌
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public void electrify(){ //通电的方法
System.out.println("正在通电中!!");
}
public void pressJuice(String fruit){ //榨汁的方法
System.out.println(fruit+"汁");
}
public String toString(){
return "brand:"+brand+"\n"+"price:"+price;
}
}
//ZhaZhiJiTest .java
package com.homework;
public class ZhaZhiJiTest {
public static void main(String[] args) {
ZhaZhiJi z1=new ZhaZhiJi();
z1.setPrice(120);
z1.setBrand("恩优希");
System.out.println(z1);
z1.electrify();
z1.pressJuice("西瓜");
z1.pressJuice("苹果");
}
}
//Rect.java
package com.homework;
/*2、写一个长方形的类,类中的属性:长方形的长,宽。类中有方法:
(一)移动的方法,没有返回值,要求输出“长方形在移动”。
(二)变化的方法,没有返回值,要求输出“长方形正在变化”。
(三)显示此长方形信息的方法。
(四)得到长方形周长的方法。返回此长方形的周长。
(五)得到长方形的面积的方法,返回此长方形面积。*/
public class Rect {
int height; //长方形的高
int weight; //长方形的宽
public void setHeight(int height){
this.height=height;
}
public int getHeight(){
return height;
}
public void setWeight(int weight){
this.weight=weight;
}
public int getWeight(){
return weight;
}
public void move(){ //移动的方法
System.out.println("长方形正在移动!!");
}
public void change(){ //变化的方法
System.out.println("长方形正在变化!!");
}
public String toString(){ //显示长方形信息的方法
return "height:"+height+"\n"+"weight:"+weight;
}
public int girth(){ //周长
int girth=(height+weight)*2;
return girth;
}
public int square(){ //面积
int square=height*weight;
return square;
}
}
//RectTest.java
package com.homework;
public class RectTest {
public static void main(String[] args) {
Rect rect=new Rect();
rect.setHeight(10);
rect.setWeight(20);
System.out.println(rect); //显示长和宽
rect.move(); //移动
rect.change(); //变化
int girth=rect.girth(); //返回周长
System.out.println("("+rect.getHeight()+"+"+rect.getWeight()+")"+"*2"+"="+girth);
int square=rect.square(); //返回面积
System.out.println(rect.getHeight()+"*"+rect.getWeight()+"="+square);
}
}