Java面向对象1

内容都是根据B站宋红康老师的视频总结以便复习的..

面向对象和面向过程都是编程思想,面向对象是相对于面向过程而言的,面向过程强调的是功能和行为,以函数为最小单位,考虑怎么做.面向对象,将功能封装进对象,强调具备了功能的对象(实例化),以类/对象为最小单位,考虑谁来做.
例子:把大象装进冰箱面向过程:打开冰箱 ; 抬起大象,装进冰箱; 关闭冰箱
面向对象: 面向对象则是对人类抽象,实现怎么样的行为,对冰箱进行抽象,有什么样的属性,对大象进行抽象,又会有什么样的行为. 设计类,类就是现实世界中名词的抽象,由谁来做,做的主体,这个问题解决了再来实现实例化. 

两者的代码量差距不大,但是类可以更好的扩展, 只要设计好各种各样的类,然后再去设计子系统与子模块, 这样的面向对象的优势才能体现,一般在代码量比较大的项目中优势更大. 
再举个例子,初创企业,员工很少,有活干活,都来干, 但是成熟企业,划分各个部门,有相应的规章制度,谁来干都是很清晰的.

面向对象中的两个基本要素:类和对象.class和Object是面向对象的核心概念,类是一类事物的描述,.是抽象的概念和定义,对象是实际存在的该类事物的每个个体,因而也被称为实例(instance).
面向对象程序设计就是类的设计,而类的设计就是类的成员的设计.

class Person{
    //什么都没写,其实这也是个类
}

类的结构:属性和方法
Java代码世界是由各种各样的类构成的,(但是还有个概念是接口).
属性,(filed) 也叫成员变量,有些翻译为字段/域, 但其实就是属性,
方法,method,也叫成员方法.

类和对象的使用就是面向对象思想的实现

1创建类 .这是最复杂的一步,Java有没有生命力,就看有没有很多人去设计强大的类库,包括第三方开源的框架.

class Person{//后面没有大括号,这里类前面也没有修饰符
    String name;
    int age;
    boolean isMale;
    public void eat(){//目前方法前面统一用public修饰符 这是一个方法,返回值为void
        System.out.println("正在吃");
    }
    public void sleep(int time){ //这个方法有参数
        System.out.println("睡"+time+"分钟");
    }

}



下面两步是在main方法中编写的,而Person类则是创建在我们的测试类之外(如 public class Test{})
2 创建类的对象 
Person p1 =new Person();//new操作符new出对象
创建对象的格式是 类型 变量名 = new 类型();
这样就创建了对象p1.

3 通过对象.属性 对象.方法() 调用对象的结构
p1.name = "Tim";
p1.age =20;  
//上面给属性赋值

p1.eat();
p1.sleep(5); // 调用方法








对象和对象创建的再理解,白马非马这个故事中,白马只是马类的一个实例化,颜色属性是白色,或者它是马类的一个继承,颜色属性是白色.创建类就是设计图纸,图纸造出来了就是根据图纸去创建一个个实体对象. 有一个对象,能调属性/方法,我们根据这个对象反推出类来,Java高级中要讲的反射.

体会多个对象之间的关系.

根据上面的代码,再创建一个p2对象 
Person p2 =new Person(); 
 
p2.name 打印出来是null,而非报错,String的默认初始化值是null 
注意打印p2是地址, p2我们已经new好了,它是栈空间对堆空间的引用,
指向了堆空间p2对象的地址. 

同样的,打印p2.isMale是false

我们此时new了两次, 堆空间有两个对象,每个对象都有各自独立的属性(非static的)
这意味着修改p1 或者 p2 ,它们之间没有影响,不会影响两个对象在堆空间中各自的独立.

Person p3 =p1;
跟上面创建对象不一样,我们创建了一个Person类型的变量,把p1赋值给它,
其实在在栈空间多了一个变量p3,它得到了p1的地址,和p1同时指向了堆空间中对应的对象.
p3.name打印出来是Tom;
p3.age =222;
p1.age打印出来是222

对象的内存解析

 JVM规定的内存结构图,这是完整的,.栈(虚拟机栈)存放局部变量,方法执行完,自动释放.堆,存放new出来的结构,对象和数组等 .方法区,存储已被加载的类信息,常量(字符串常量池),静态变量(也叫静态域,static关键字)以及即时编译器编译后的代码等数据.

堆(Heap),此内存区域的唯一目的
就是存放对象实例,几乎所有的对象
实例都在这里分配内存。这一点在
Java虚拟机规范中的描述是:所有的
对象实例以及数组都要在堆上分配。  通常所说的栈(Stack),是指虚拟机
栈。虚拟机栈用于存储局部变量等。
局部变量表存放了编译期可知长度的
各种基本数据类型(boolean、byte、
char 、 short 、 int 、 float 、 long 、
double)、对象引用(reference类型,
它不等同于对象本身,是对象在堆内
存的首地址)。 方法执行完,自动释
放。  方法区(Method Area),用于存储已
被虚拟机加载的类信息、常量、静态
变量、即时编译器编译后的代码等数
据
对象的内存解析:
Person p1 = new Person(); 
new 创建对象,在堆内有个首地址值,把这个地址值赋值给p1,
p1是在main方法中创建的变量,方法中创建的变量都是局部变量.
局部变量都存放在栈空间中,p1在栈空间中,值为p1对象的首地址值,
属性在堆空间中有默认初始化值,和数组一样,
name 字符串的默认初始化值是null
age int的默认初始化值是0
isMale的默认初始化值是false

p1.name = "Tom",
找到堆空间的中的p1对象,name属性赋值为"Tom",覆盖了原来的null.事实上,"Tom"不保存在堆空间中,在字符串常量池内,属于方法区
p1.isMale =true;
同样是 把isMale属性赋值为true

Person p2 = new Person(); 同样是创建了一个p2对象
仍然是在堆空间中有个p2对象的首地址值,赋值给栈空间中的p2变量 


System.out.println(p2.name);打印出是null,因为是默认初始化值

Person p3 =p1;
栈空间中创建了一个局部变量p3,它的值是p1对象的地址
p3.age =10;
根据地址找到所指向的p1对象的age属性,把0修改为10

设计类就是设计类的成员,再回到类的成员属性和方法.
首先介绍局部变量和属性,属性和局部变量有什么注意的.

他们的相同是定义变量的格式相同,(属性又叫成员变量), 数据类型 变量名 =变量值. 先声明,后使用. 变量都有对应的作用域.

不同点

1. 它们在类中的位置不同, 
类中定义的变量就是属性,直接再类的一对括号内,
所以在main中方法写的变量是局部变量,它们不是在类的那个{}下面直接定义的.


而局部变量在类中只出现在方法内(类定义的方法),方法形参, 代码块内/构造器形参/构造器内的变量.

class Car{
    String name;
    String color;
 
    //上面是属性 
    public void run(double speed){ //形参,是局部变量
        double speeds = speed *2; //方法中定义的变量. 局部变量
        System.out.println("我能跑"+speed+",但是我最快能跑"+speeds);
    
    }
}

2.关于权限修饰符的不同
属性:声明属性时,指明其权限,使用权限修饰符,常用的权限修饰符有 private,public,protected和缺省修饰符(前面什么都不写), 上面的属性就是用的缺省修饰符.
private String name;Car创建的对象不能调用这个属性,
...
权限修饰符体现于结构被调用的时候可见性的大小(类的封装性)


局部变量:前面不能使用权限修饰符,可以理解为方法的权限(public)就是局部变量的权限

3.关于默认初始化值.
属性的默认初始化值同数组,
byte short int -->0
long -->0L
flaoat :0.0f
double 0.0;
boolean false;
char : '\0'=0='\u0000';
引用数据类型(类,数组,接口):null


而局部变量没有默认初始化值,
在main中声明一个变量int num; 打印num会报错
类中定义一个方法 
public void write(Sring str){//如果调用方法不给实参的话就会报错,说明它没有null这个默认初始化值
    int a ;//局部变量在这里不给赋值也会报错
}


4.局部变量和属性在内存中的位置不同
属性在堆空间中 局部变量在栈空间中 

接下来讲方法,方法举例和声明的格式 
属性是变量,而方法是类中定义的功能.
Scanner 类的next 方法,Arrays类的toString方法,sort方法.equals方法
 

方法的声明:
权限修饰符 返回值类型 方法名(形参列表 args1,args2,...){

    //方法体

}
目前用到的方法的权限修饰符都是public, 当然还有没用到的static final abstract 等特殊关键字来修饰方法.

class Customer{
    String name;
    int age; 
    public void eat(){//无形参
        System.out.println("客户正在吃饭");  
    }
    public void sleep(int hour){ //有形参,调用时传入
        System.out.println("睡个"+hour+"小时");
    }
    public String getName(){
    //返回值类型是String ,有这个属性,不要形参
        return name;//返回name
    }
    public String getNation(String nation){
        String info = "我的祖国是"+nation;
        //定义了一个字符串局部变量,返回这个局部变量 
        return info;
    }
}
方法的注意点:


1.有权限修饰符,同属性,public private protected 和缺省(不写修饰符) 
关于权限修饰符在谈封装性细说 
类中定义了一个private void noSee(){},外部不能调用这个方法.


2.返回值类型
这个看实际需求,有返回值,必须给定返回值类型并且return相应的返回值
没有返回值则用void表示返回值为空

return "Tom";返回一个常量也可以,但是必须要有return关键字.
有个注意点方法要求返回一个字符串
里面有判断逻辑
if (age>19){
    return name;
}//这样是错误的,age小于19就不返回,但是声明的是需要返回值的
所以加上一个else{
    return "Tom";
}

关于返回值类型为void 我们没有写return关键字,实际上是省略了 return ;

reurn关键字的使用,使用在方法体中,作用时结束方法或者对于有返回值的方法给出返回值.

方法使用的注意点

1. 方法中可以调用类中的属性和方法 
类A中调用 属性x 
类A中的 meth1 调用meth2 ,meth1调用meth1,会导致栈溢出
那么方法名meth1应该也是存放在栈空间中的 


2. 方法中不能定义方法
public void outter(){
    public void inner(){
        ;
    }
}
这是错误的

面向对象的课后练习

我自己写的使用就脑抽了

public class HomeWork{
    public static void main(String[] args){
        ...
    }
}
这里我写的public class A{

}
现在类都写在public类下面
写class A{

}


我这样是把定义的类和测试类都写在一个文件下面了.
实际开发中,一个文件就写一个类,并且各个类还不能重名.

我定义的类创建一个文件 
public class A{//这里可以用public了

}


在主测试类的文件下
public class Atest{
    //main方法是程序的入口,入口内测试.

}
创建Person类的对象,设置该对象的name、
age和sex属性,调用study方法,输出字符串
“studying”,调用showAge()方法显示age值,调用
addAge()方法给对象的age属性值增加2岁。

class Person{
    int age;
    ...
    public addAge(int i){
        age+=i;
    }
    ...
}
代码没有写全,这里讲一下这个addAge方法,首先我们实例化了对象 p1 

不管我们给没有给p1 这个对象的age属性赋值,addAge方法都是可用的

1. 不赋值age, age在堆内是int默认值 0  
    p1.addAge(2),调用这个方法.我们创建了一个局部变量i在内存中,值是2,把age的值0+2后赋值给age;
    方法调用结束,局部变量i被当做垃圾回收.
2.赋值了age 
p1.age =18;堆空间中的属性age变为18 , 调用方法,创建局部变量i,值为2,加值赋值给age,方法调用结束,i被当做垃圾回收.
课后练习 .圆的面积 有半径属性,方法可以直接调用属性,方法不传参数.
课后练习,对象数组.
实例化二十个学生对象
因而不能用new去创建20个.
用数组,数组有20个元素,每个元素是对象.
创建Person数组 
Person[] persons = new Person[20];
new了一个数组,堆空间中有一个数组,数组有20个元素,因为元素是对象,
对象是引用数据类型,因而是默认值null
person[x]打印出来是null;
persons在栈空间,变量是Person[]数组在堆空间的首地址,

怎么实例化对象呢?
数组的元素是对象,并且Person类创建的对象.只是还没创建,
相当于 
每个元素都是 Person p;
把每个实例对象new出来就行了 
for (int i =0;i<persons.lenth;i++)
{
    persons[i] = new Person();
    //每个元素从原来的null,变成得到一个Person对象的首地址
    //创建了20个对象,
}


类定义
class Person{
    ...
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值