一、面向对象思想
先学面向过程思想:是以前计算机科学发展到一定阶段的产物,后学的面向对象思想也是计算机科学发展到一定阶段必然产生一个产物
面向对象思想基于面向过程的
面向过程的编程风格:在main方法的下面有很多其他的功能代码(方法),五花八门(可以有短信方法,支付方法,时间方法)如果都像面向过程放在一个代码里面,管理维护不方便
面向对象的编程风格:化繁为简,把main下面相同类似的方法封装成一个class,这个类的类名(Date.java),它里面只有与日期时间相关的方法,后续扩展功能或者修改程序的错误,
可以快速定位
二、类与对象及其使用
物以稀为贵,现在是脑力社会时代
软件是为了人们服务的,只有你的软件满足了现实生活中人们的需求你的产品才会有很高价值,用户才会多。有一个问题,软件是虚拟的,而管理的事物在生活中
确实真实存在的
虚拟的软件要不要和现实进行一一匹配(学生管理系统,汽车管理系统)系统软件和现实人(学生、汽车对应上)
在java语言中基本组成单位是类,现实生活中我们也是说类(我去开车:类)
现实生活中的: 虚拟的
学生: class Student {
属性:姓名、年龄、学号 String name、int age、String number;
能力方法:吃饭,睡觉 public void eat() {} public void sleep() {}
}
对象的内存图
内存中有三个区域:
方法区、栈内存、堆内存
方法区:代码仓库,cmd运行程序时加载的class字节码文件在此
栈内存:局部变量
堆内存:new出来的对象、每new一个多一个,不要我们管理java垃圾回收机制会自动处理
成员变量和局部变量的区别
位置:
成员变量:类里方法外
局部变量:方法的声明上(圆括号),方法里面(大括号)
内存:
成员变量:堆内存给它默认值:byte、short、int、long(0)float、double(0.0)、char('\u0000')、boolean(false),引用类型(null)
局部变量:栈内存要赋值初始化
生命周期:
成员变量:随着对象被垃圾回收机制回收后消失
局部变量:方法出栈,消失
匿名对象
省去变量名的对象new 类名();只能使用一次
封装(private)
属性private(必须),给每个属性setXxx和getXxx方法,可以做安全校验,他人调用你的校验细节隐藏不知道,程序健壮安全
this关键字
不管是局部变量还是成员变量(见名知意)成员变量和局部变量名字相同时用this指代当前对象,用this修饰成员变量
三、代码块
代码块表示一个范围。在java语言中{}表示包含一个范围
写在方法中(局部代码块)
public void method1() {
{
int x = 100;// 局部代码块中的一个变量,使用后会立即释放
}
// 局部代码块外不能访问局部代码块内的变量
}
写在类中:1、构造代码块
class ClassA {
{
System.out.println("构造代码块");// 优先于构造方法执行,且每new一个对象都会执行
}
public ClassA() {
}
}
2、static代码块
class ClassB {
static {
System.out.println("静态代码块");// 在加载字节码文件的时候加载,方法区中的静态区,加载一次
}
}
继承(重点、难点、掌握)
继承语法概述:
之前写程序为了复用我们写在方法中,反复调用即可。但是随着方法变多,和方法的功能混杂,我们一组类似的方法抽取封装成一个类。
类可以创建对象,且可以创建n个对象,类可以看成一个模板,是另一种复用。当我们学习面向对象之后让人烦恼的事情:类爆炸,程序员工作量瞬间增加
在模板这个设计的角度来说可以运用中国古老的一种变成风格(活字印刷术),提醒了我们class,还能够进行更加灵活的复用:继承
继承的格式:只能用在类上(子类,父类)
父类:表现形式上,就是一个普通的类:class 类名
子类:表现上是不同的类,类名的后面是要继承的父类:class 子类名 extends 父类名
继承的好处:子类中,很多的方法,不用重复写,可以都写在父类中,可维护性好,复用
弊端:耦合性增强
继承中成员变量的特点:父类和子类的成员变量不相同(可以直接使用父子类中的成员变量)
父类和子类的成员变量名相同了(this表示子类和super表示父类调用)
举例:this.name(调用子类的属性姓名)super.age(表示调用父类的属性年龄)
class A {
int num = 30;
}
class B extends A {
int num = 20;
public void method() {
int num = 10;
System.out.println(num);
System.out.println(this.num); -------|在类的属性中去查找
System.out.println(super.num); -------|
}
}
继承中构造方法的特点:
子类在初始化的时候,先做父类的构造方法初始化,再做子类的构造方法(默认的子类方法中都是父类的无参数的构造方法)
如果父类没有给我提供默认的无参数的构造方法:
1、自己手动加载无参数的构造方法
2、用手动的方式调用父类有参数的构造方法
class Fu {
public Fu(String name) {
// ...
}
}
class Zi extends Fu {
public Zi(String name) {
super(name);
}
}
3、在子类中使用this调用有参数的构造方法
class Fu {
public Fu(String name) {
// ...
}
}
class Zi extends Fu {
public Zi() {
// 注意由于Fu类中没有默认的构造方法了,只能通过this自己调用自己
this("刘德华");// 不常用
}
public Zi(String name) {
super(name);
}
}
继承中成员方法的特点:
如果方法名不相同,可以直接调用
如果子类方法和父类的方法一模一样,那么子类覆盖父类的方法(叫重写),是给多态准备(明天将多态)就近原则
重写:
父类中的某个方法是最通用的,在业务逻辑中满足大部分需求,所以才放在父类中公用。
子类的某个方法需要有自己的独特的特性,那么就要重写父类的方法了,但是重写的过程中,还是依然可以做父类的方法的调用super.方法名()。
只需要做略微的变化就可以了,子类可以继承使用父类,还可以扩展父类的功能
重载、重写的区别:
首先要对这两个概念非常清楚
重载是针对于一个类中方法的
方法名字定义成一个是方便程序员使用,但是根据参数的方式自行匹配
重写是针对于继承机制中的多个类的方法
重写的目的,对父类的代码进行扩展,或者变化特别大完全覆盖
final关键字
final:终结的终止的最终的
final局部变量:
还能否二次赋值?(不能,用final修饰的变量类型其实发生了质的变化:自定义常量)
字面值常量:基于基本数据类型
final方法:
不能被子类重写,可以被子类使用
final类:
所有的方法都不想被重写(安全),当前类用final标识
final如果将变量变成常量:
final后面的变量名:单个单词全大写final double PI = 3.1415926;、多个单词全大写且用下划线连接final int MIN_INIT_NUMBER = 1;
final修饰后的常量是依附于对象的,而我们希望加上public static 依附于类。通过类名.常量名直接访问
final修饰的是基本数据类型:不能赋值
修饰的是引用数据类型:能赋值,不能更改其引用地址
|
|