一:面向对象
基本概念:面向对象是一种思想,是相对于面向过程而言的,相对简单。通过这种思想可以把生活中的复杂事情变得简单化,从原来的执行者变成了指挥者。
三个特征:
- 封装:把相关的数据封装成一个“类”组件,更具有安全性,也更方便,可复用。
- 继承:是子类自动共享父类属性和方法,这是类之间的一种关系。
- 多态:增强软件的灵活性和重用性。
二:类和对象
类:
1、 Java语言最基本单位就是类,类似于类型。
2、 类是一类事物的抽象。
3、 可以理解为模板或者设计图纸。
对象:
每个对象具有三个特点:对象的状态,对象的行为和对象的标识。
1、 对象的状态用来描述对象的基本特征。
2、 对象的行为用来描述对象的功能。
3、 对象的标识是指对象在内存中都有一个唯一的地址用来和其他对象区分开来。
4、 类是一类事物的抽象,对象是具体的实现。
三:类和对象的创建和使用
通过class创建类、
通过new创建对象。
练习一:类和对象的创建
/**
* 测试类和对象
* 一个.class文件中,只能有一个用public修饰的类,并且这个类名要和文件名相同
* */
public class Test_Class {
public static void main(String[] args) {
new Car();//匿名对象
Car bmw=new Car();//创建对象
bmw.go();//使用模板中的功能
}
}
/**
*使用class来创建汽车类,用来描述汽车事物
* @author 小白
*
*/
class Car{
// 描述事物的特征:用成员变量-类里方法外
// 型号、颜色、价格、配置
// 描述事物的功能:用成员方法
String model;
String color;
double price;
String collocation;
/**
* 前进
*/
public void go() {
System.out.println("go()....");
}
/**
* 后退
*/
public void back() {
System.out.println("back()....");
}
}
对象在内存中的存储:
说对象在内存中的存储之前,先了解一下java内存的5大区域,1栈,栈的内存非常小,但是它的存取速度特别快,所以在栈中存的一般都是快速执行的任务。例如基本数据类型的数据或者对象的引用。2堆,类对象一般存在堆中,所有的对象在创建的时候都是通过new来创建的,创建之后再占中存储唯一的引用地址。3PC寄存器,每一个线程都会有它自己的寄存器,是在启动的时候创建的,在寄存器中存的是当前执行的JVM指令的地址。4本地方法栈,它存的是本地方法进入区域的地址。5方法区,也叫静态区,它存储的是所有的类,静态变量,静态方法,常量,成员方法。所以,说到对象在内存中的存储,我们重点要关注的就是内存中的堆和栈。如下图:值得注意的是,如果对象没有进行赋值的话,它也是有默认值的。另外,如果堆和栈中存储多个对象,创建也是一样的,只不过它们不是在一个内存空间的,只要是new,就开辟新的内存空间,使用也是一样的,只不过在释放的时候,有栈的特点,例如下图中,P在P2的底部,P2在P3的底部,如果P2,P3的内存不释放的话,那么P1的内存是无法释放的。
练习二:创建多个类
//用来测试
public class Test3_Person {
public static void main(String[] args) {
Person p=new Person();//创建类1
p.eat();
Person p1=new Person();//创建类2
p1.sleep();
}
}
class Person{
public String name;
public int id;
public void eat() {
System.out.println("eat()....");
}
public void sleep() {
System.out.println("sleep()....");
}
}
结果:
四:封装
封装是指,隐藏对象的属性和实现细节,只对外部提供访问方式。
它的好处:提 高安全性,重用性。
private关键字:是一个权限修饰符,用来修饰成员变量和成员方法,被私有的成员和方法只能在类内访问,如果想要修改,只能通过提供的get和set方法。
练习一:封装学生
//用来测试
public class Test4_Private {
public static void main(String[] args) {
Student stu=new Student();
//如果设置成私有的,就不能通过之前的点来获取的修改了,要通过get方法获取。
stu.getName();
//如果test方法被设置成了private方法,就不能通过点来调用了,如果真的想用,可以将这个private方法写在一个public方法中
// stu.test();
stu.testPub();
}
}
class Student{
private String name;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void testPub() {
test();
}
private void test() {
System.out.println("考试......");
}
}
结果:
五:创建对象的流程
六:构造方法
构造方法:构造方法是一种特殊的方法,它是一个与类同名,且返回值是同名类类型的方法,对象的创建就是由构造函数完成的,其主要就是完成对象的创建和对对象的初始化,当实例化一个对象就会自动调用构造方法,构造方法和其他方法一样,也可以重载。
格式:可以无参也可以有参
修饰符 类名(参数){
代码}
练习一:使用带参构造
package cn.tedu.oop;
//用来测试
public class Test1 {
public static void main(String[] args) {
Student sd=new Student("小明");
System.out.println(sd.getName());
}
}
class Student{
private String name;
//无参构造方法,不重写的话系统会自动定义
public Student() {}
//含参的构造方法
public Student(String name) {
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
结果:
七:构造代码块和局部代码块
构造代码块和局部代码块
代码块:就是一段代码被一对{}括起来的现象。
代码块随着位置的不同,意义也不同,如果代码块在成员位置(类里方法外),叫做构造代码块,代码块如果在局部位置(方法里),叫做局部代码块。
构造代码块:构造代码块通常是用于抽取构造方法中的共性代码,每次调用构造方法都会提前调用构造代码块。它优先于构造方法加载。
局部代码块,通常用于控制变量的作用域,出了括号就失效。变量的范围越小越好,成员变量有线程安全问题。
执行顺序:构造代码块优先执行,局部代码块顺序执行。
练习一:测试执行顺序
public class Test2_Block {
public static void main(String[] args) {
new Person();
}
}
/**
* 测试构造代码块优先于构造方法加载的。
* @author Administrator
*
*/
class Person{
//构造代码块:构造位置
{
System.out.println("构造代码块");
}
public Person() {
System.out.println("无参构造");
}
}
结果:
练习二:抽取共性
package cn.tedu.oop;
public class Test2_Block {
public static void main(String[] args) {
//可以看出,在创建对象时才触发构造代码块和构造方法,不创建就没有
new Person();
new Person("张亮");
}
}
/**
* 测试构造代码块优先于构造方法加载的。
* @author Administrator
*构造代码块通常用于抽取构造方法里的共性
*/
class Person{
String country;
//构造代码块:构造位置
{
System.out.println("构造代码块");
country="中国";
}
public Person() {
System.out.println("无参构造"+country);
}
public Person(String name) {
System.out.println("带参构造"+country);
}
}
结果:
练习三:局部代码块
package cn.tedu.oop;
public class Test2_Block {
public static void main(String[] args) {
//可以看出,在创建对象时才触发构造代码块和构造方法,不创建就没有
new Person();
new Person("张亮").show();
}
}
/**
* 测试构造代码块优先于构造方法加载的。
* @author Administrator
*构造代码块通常用于抽取构造方法里的共性
*/
class Person{
String country;
//构造代码块:构造位置
{
System.out.println("构造代码块");
country="中国";
}
public Person() {
System.out.println("无参构造"+country);
}
public Person(String name) {
System.out.println("带参构造"+country);
}
public void show() {
//局部代码块,在方法里
int sum=10;
System.out.println("局部代码块 "+sum);
}
// 不能用,只在代码块里有效
// System.out.println("局部代码块 "+sum);
}
结果:
八:this关键字
代表本类对象的引用对象。
使用场景:变量名相同时使用,构造方法间的调用。
练习一:this使用的使用一(变量名)
package cn.tedu.oop;
public class Test3_ThisUse {
public static void main(String[] args) {
new Student1().show();
}
}
//创建一个student类
class Student1{
// 成员变量:类里方法外
int count;
int sum=20;
//TODO 提供普通方法
public void show() {
int sum=10;//局部变量在方法里,使用时需赋值
System.out.println(sum);
//变量就近原则,使用局部sum
System.out.println(count);
//局部变量和成员变量重名了,想用成员变量,用到this,相当于底层创建一个本类的对象,用创建好的对象去点
System.out.println(this.sum);
}
}
结果:
练习二:this的使用二(构造方法)
package cn.tedu.oop;
//构造方法间相互调用
public class Test4_ThisUse2 {
public static void main(String[] args) {
new ThisDemo();
new ThisDemo("小明");
}
}
class ThisDemo{
public ThisDemo() {
// 无参构造调用含参
this("张亮");
System.out.println("无参构造");
}
public ThisDemo(String name) {
//在含参构造中 调用无参构造
//this();
System.out.println("含参构造"+name);
}
}
结果:
这里要主语,如果this关键字出现在构造方法里,必须放在第一条语句。