面向对象
java的语法
代码的基本组成
注释
关键字
标识符
硬性
软性
数据
常量
变量
数据类型
基本
byte short int long float double boolean char
引用
数组
类
接口
变量的注意事项
重复
连续
赋值
范围
FL
键盘录入
类型转换
隐式
强制
注意事项
符号
基本
运算
算术
赋值
比较
逻辑
三元
位
结构语句
顺序
选择 ifswitch
循环 forwhiledowhile breakcontinue
函数(方法)
作用
使用无参无返回
参数
返回值
注意事项 void return
重载
参数传递
面向对像
封装
继承 extends
多态
static
final
public private protected 默认
今日内容:
面向对象思想(☆☆☆) :
java的为什么火:
面向对象语言
开源
跨平平
面向过程:
其实就是 面向的这个过程。
生活案例:洗衣服这个过程, 把衣服扔到盆里 --放上水泡上--放洗衣液--揉洗 --拧干--涮一遍--拧干--晾干
程序中 :如果洗衣服这个过程类比到代码中,这个过程的每一行代码 都需要你自己去写。
面向对象 :
你面向的不再是过程了, 而是面向的是这个对象。
生活案例:你不需要面向洗衣机这个过程了, 你找一个洗衣机过来, 把洗衣放到洗衣机里面去(把衣服扔到盆里 --放上水泡上--放洗衣液--揉洗 --拧干--涮一遍--拧干--晾干);
现在你发现 面向的不是那个洗衣服的过程了吧, 你面向的是洗衣机啦。 我们只需要他去做事情就可以啦。
程序中: 洗衣服的这个过程 你不需要去写啦。 你只需要写一行 调用洗衣服的代码就可以啦。
疑问:
问题: 洗衣机拿来的呢? 你不要还是要去写 洗衣机里面这个过程的代码吗?
回到现实生活中:
如果你去洗衣服, 请问 您去造一个一洗衣机吗?? 会吗??
你有三种方式来指挥洗衣机帮你去做事情:
1:自己造一个。
2:你家里面本身就有一个洗衣机。
3:你买一个洗衣机 来洗衣服。
回到代码中:
你也有三种方式 调用洗衣机
1:你也去自己造一个, 自己手写 洗衣机洗衣服的这个过程。
2:jdk包括 jre 里面包括一个 核心类库, jre的核心类库里面就提供了大量的类似于洗衣机的这样的类, 你直接调用就可以啦。
3:其实市面上有很多的 软件公司 生产类似于洗衣机这样 代码。 你只需要从他们买过来代码 放到你自己的程序中, 直接调用就可以啦。
所以今天学学自己怎么去定义 一个类似于洗衣机这种的东西:
类: 类 是对 这种事物类型的描述。
对象: 真正让洗衣机工作的时候, 我们需要通过对 洗衣机的描述 去内存中创建出一个实实在在的洗衣机。
面向对象的作用:
其实面向对象, 代码去执行的过程, 也是基于面向过程的,所以面向对象根本不会提高程序的执行效率,甚至有一丁点的 减低了程序的执行效率。
因为多了一步调用的过程。
他提高了我们开发人员的开发效率。
c语言是 世界上最快的语言,c语言是面向过程语言。
类和对象(☆☆☆☆☆) :
类:对一类事物的描述 模板 设计图...
属性: 用变量去表示。
功能: 用方法去表示。
对象:是这一类事物中 一个具体的存在。
案例2:定义学生类 创建学生对象
// 模板 设计图
public class Student {
// 类是模板, 是对事物的描述
// 事物应该具备 属性(学生的那些值) 行为
// 属性 : 成员变量 (类中方法外面)
// 行为 : 比较复杂的顺序 逻辑 ... 应该是一系列的语句来组成, 所以我们把这些语句写在方法内, 行为用方法来表示。
//System.out.println("sdf");
// 属性: 年龄 30 20 25 ....
int age;
// 属性: 姓名 "张三" "李四"
String name;
// 行为 学习 吃饭
public void study(){
System.out.println("学生学习");
}
public void eat(){
System.out.println("学生吃饭");
}
// 行为 帮老师去买冰糕
public char buyBingGao(int money){
System.out.println("用"+money+"元 去买了一根冰糕");
return '糕';
}
}
public class Demo1 {
public static void main(String[] args) {
// 根据Student 这个设计图 创建一个具体的 学生。
// 创建对象
// 格式
// 类名 对象名 = new 类名();
Student stu = new Student();
// stu 就是那个实实在在的对象。
// 指挥对象 做事情。
// 对象名.属性名
// 对象名.方法()
System.out.println(stu.age);
System.out.println(stu.name);
stu.age = 23;
stu.name="张三";
System.out.println(stu.age);
System.out.println(stu.name);
stu.study();
stu.eat();
char c = stu.buyBingGao(10);
System.out.println("我作为老师就拿到了你给我买的"+c);
//----------------------------------
//Random // 这是jre核心类库里面提供的一个类。
Random r = new Random();
int anInt = r.nextInt(100);
}
}
案例3:定义一个手机类, 并且创建手机对象并使用
手机的属性有:品牌 价格 颜色
手机的行为有: 打电话发短信
class Phone {
String brand;
double price;
String color;
public void call(){
System.out.println("打电话");
}
public void sendMessege(){
System.out.println("发短信");
}
}
class Demo {
public static void main(String[] args){
Phone ph = new Phone();
System.out.println(ph.brand); //null
System.out.println(ph.price); //0.0
System.out.println(ph.color); //null
ph.brand = "apple";
ph.price = 9999.9;
ph.color = "炫酷紫"
System.out.println(ph.brand); //apple
System.out.println(ph.price); //9999.9
System.out.println(ph.color); //炫酷紫
ph.call(); // 打电话
ph.sendMessege();// 发短信
}
}
内存图(☆☆☆):
一个对象的内存图:
方法区 是用来存储 类的 字节码文件的, 就是代码的存储位置。
堆内存 用来存储 对象的数据的。
栈内存 代码一句一句的执行 在栈里面发生的, 栈里面是以方法为单位。
类的代码存储在 方法区中的。
对象 是创建在 堆内存中的, 我们给对象中的属性赋值, 是赋值到堆内存中的。
class Demo {
public static void main(String[] args){
Phone ph = new Phone();
System.out.println(ph); // 地址
}
}
两个对象的内存图:
类的字节码文件, 只有第一次使用到的时候, 加载一次, 以后再执行到的时候 就不再加载了。
类的字节码文件在 方法区的存储,是跟着jvm的, 只要jvm不停止, 方法区里面的东西就不会清楚。
引用类型的数据 每new一次 就是要在堆内存开辟新的空间。
class Demo {
public static void main(String[] args){
Phone ph = new Phone();
ph.brand = "大米";
System.out.println(ph.brand); //大米
Phone ph1 = new Phone();
ph1.brand = "长粒米";
System.out.println(ph.brand); // 大米
}
}
两个变量指向同一个对象的内存图:
可以多个变量同时去操作 一个对象(堆内存中的), 只要其中一个通过变量去变量 对象里面的内容,第二变量再去使用对象里面的内容的时候 就已经发生改变了。
Student s = new Student();
s.name = "张三";
Student stu = s;
stu.name = "李四";
System.out.println(s.name + stu.name); // 李四李四
当一个应用类型变量 不指向堆内存中任何内容了, 这时候再通过这个变量去访问内容 就会报空指针异常
Studnet stu = null;
System.out.println(stu.name); // 空指针异常
垃圾回收:
栈内存:方法被调用 就会在栈内存存在,
方法执行结束之后,从栈内存中消失了,包括里面的 变量 以及基本类型的数据值 都消失了。
堆内存:当指向这个堆内存中的对象的 所有的变量 都消失了的时候。
这时候 这个对象 就会变成内存垃圾,但是并不会立刻消失。
而是 java底层有一个垃圾回收机制 定时轮训 每隔一段时间就去检测垃圾,并且回收垃圾。
方法区:方法区中的内容, 只要jvm不关闭,任何时候都不消失。
class Demo {
public static void main(String[] args){
show();
System.out.println("main方法不结束了");
}
public static void show(){
int a = 10;
Student s = new Student();
}
}
成员变量和局部变量的区别(☆☆☆☆☆):
// java的中一切的代码 除了两条语句之外 其他所有所有的代码 必须写在类中, 类是java的基本单位
//package com.itheima;
//import java.util.Scanner;
class Student {
int age; // 类中 方法外面 定义的 成员变量
public void show(){
int a = 10; // 方法里面定义的变量 局部变量。 我们之前所遇到的所有的变量 全部都是局部变量
System.out.println(a);
}
}
定义位置:
成员变量: 类中 方法外面
局部变量: 方法内部
内存位置:
成员变量: 堆内存, 因为他在对象里面, 对象在堆内存。
局部变量: 栈内存, 跟着方法走, 方法在栈里面执行。
生命周期:
成员变量: 随着对象的创建而存在(存在于对象里面),随着对象的消失而消失。
对象何时消失呢?
当栈内存中 没有任何的变量 再去指向 这个对象了, 那么 这个对象就会被 java底层的垃圾回收器 认定为垃圾。
垃圾回收器 定期轮巡执行的。 轮巡到那儿的时候 就会清理掉。
局部变量 : 随着方法的调用进栈 存在, 随着方法调用完毕 弹栈而消失。
初始化:
成员变量: 有默认值的,所以使用之前 是不需要赋值的, 直接使用他的默认值就可以。
局部变量: 没有默认值。所以 使用之前 必须先赋值。
private (☆☆☆☆☆)
private只能修饰 成员 不能修饰局部, 被private修饰的成员 不能在类的外部直接访问的。 只能在类内部访问
public class Student {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int a) {
age = a;
}
public String getName() {
return name;
}
public void setName(String n) {
name = n;
}
}
public class Demo {
public static void main(String[] args){
Student s = new Student();
//s.age = 10;
s.setAge(10);
int a = s.getAge();
System.out.println(a);
}
}
this (☆☆☆☆☆)
回顾变量的注意事项
class Demo {
public static void main(String[] args){
int a = 10;
{
int a = 20; //编译报错 重复定义。 因为 这两个a 都在栈内存中。
}
//System.out.println(a); //
}
}
就近原则:
class Student {
int a = 10; // a 在堆内存中, 属于对象的。
public void show(){
int a = 20; //正确的 不报错 a在栈内存中 属于方法show方法里面的。
System.out.println(a); //20
}
}
class Car {
int a = 10;
public void show(){
System.out.println(a); //10
}
}
this打破就近原则:
局部变量是无法通过对象直接调用的:
public class Student {
int age;
public void show(){
int aa=10;
System.out.println(aa);
}
}
public class Demo {
public static void main(String[] args) {
// 此处如何拿到age
Student stu = new Student();
System.out.println(stu.age);
//如何拿到aa
//System.out.println(stu.aa); //编译报错 。局部变量拿不了。 因为 局部变量 在栈里面 随着方法调用才存在, 方法没调用 aa是不存在的
// 所以局部变量 只有在show方法内部去使用。
stu.show();
}
}
this代表的是对象。 对象.变量 此处调用的变量是 成员变量。 所以this.a 此处的a就是成员变量。
class Student {
int a = 10;
public void show(){
int a = 20;
System.out.println(this.a); //10
}
}
this 指的是一个"动态"的对象 , 谁来调用包含this的这个方法,this就指的是谁
public class Phone {
public void show(){
System.out.println(this);
}
}
class Car {
int a;
}
class Demo {
public static void main(String[] args){
Phone ppx = new Phone();
System.out.println(ppx); //0x001
ppx.show(); //0x001
Phone ppx1 = new Phone();
System.out.println(ppx1); //0x002
ppx1.show(); //0x002
Car c = new Car();
System.out.println(c); //0x003
//c.show(); //编译报错 因为 Car 中没有show方法。
//谁来调用包含this的这个方法 this就指的是谁。
// 只有是这个类的对象可以调用, 所以 “谁”只能是本类对象。
}
}
jdk设计 this 这个语法的原理:
高格局
构造方法(☆☆☆☆☆)
基本符号:
() : 类型转换
运算
结构语句
方法的定义和调用。
构造方法: 用来创建对象 所必需要执行的方法。
定义格式:
1: 方法名字 必须和类名一摸一样
2: 构造方法 没有返回值类型的 void也不能有
3: 构造方法必须 只能用 new来调用。
4: 不能写返回值 (但是可以单独写一个 return , 目的是为了强制终止构造方法)
class Student {
public Student(){ // 这就是Student类的一个构造方法。
}
}
调用:
构造方法的作用是创建对象, 只能使用new 调用, 用来创建对象。
不能使用对象去调用。
class Student{
public Student(){
System.out.println("构造方法执行");
}
}
class Demo {
public static void main(String[] args){
Studnet s = new Student(); // 构造方法执行
Student s1 = new Student(); // 构造方法执行
//s.Student(); // 编译报错
}
}
//-----------------------------------------
class Phone{
public Phone(){
System.out.println("Phone构造方法执行");
}
public void Phone( ){ // 这个方法 就相当于 一个 普通类似举例那种 show方法。 只不过名字 我不叫show了 叫Phone
System.out.println("这是一个普通方法 名字叫Phone(恰好方法名和类名相同了 你管得着吗) 不是构造方法");
}
public void show(){
System.out.println("这是一个普通方法 名字叫show 不是构造方法");
}
}
class Demo {
public static void main(String[] args){
Phone s = new Phone(); // Phone构造方法执行
Phone s1 = new Phone(); // Phone构造方法执行
s.Phone(); // 可以 正确 但是 Phone() 这不是构造方法了。
s.show();
}
}
注意事项:
1:构造方法 顾名思义 "构造" 也就是说 这个方法是为了创建对象而存在的,换句话说, 如果一个类中没有构造方法 那么这个类创建不了对象。
public class Student {
/*
如果一个类中 没有手动写出构造方法
那么系统 会提供给你一个 构造方法
public Student(){
}
手动写出构造方法之后
系统就不再提供了
*/
public Student(){
System.out.println("sdfsdf");
}
}
public class Demo {
public static void main(String[] args) {
Student s = new Student();
// 然而 这个类却能创建对象
// 说明这个类中有构造方法。
System.out.println(s);
}
}
2:构造方法可以重载
public class Phone {
/*
构造方法 是不是属于方法。
方法的重载
构造方法也必然存在着重载这种现象
方法名名相同 参数列表必须不同
*/
/*public Phone(){
System.out.println("没有参数的构造方法--无参构造");
}*/
public Phone(int a){
System.out.println("有参数的构造方法--有参构造");
}
/*
如果我们没有手动写出构造方法
系统将会默认提供一个 无参数的构造方法
public Phone(){ }
如果我要手动给出了 系统就不再提供了。
*/
}
public class Demo1 {
public static void main(String[] args) {
//Phone p = new Phone(); //编译报错
Phone p1 = new Phone(10);
}
}
3:构造方法作用, 在创建对象的时候 顺便给 属性赋值
public class Car {
private String brand;
private int price;
public Car(){
}
public Car(String brand, int price){
this.brand = brand;
this.price = price;
}
public void setBrand(String brand) {
this.brand = brand;
}
public void setPrice(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
public String getBrand() {
return brand;
}
}
public class Demo2 {
public static void main(String[] args) {
// 构造方法是创建对象而生的。
// 系统给一个 我也能创建对象, 你给了也能用你的 , 有什么区别吗?
Car c = new Car();
c.setBrand("宝驴");
c.setPrice(199);
//这就是我们创建一个 汽车对象 并把他的属性 弄好的。
// 三句话。 你用了三条语句。
// 我觉得三条语句有点麻烦,
//以后万一 他有1万个属性呢 你需要写1万01条语句
// 那能不能 一条语句结束呢
// 无论你想用几条语句 你必须得有创建对象的那条语句。
// 那我就在想 能不能在创建对象的时候 就给我赋值呢??
Car c1 = new Car("奔马",299);
System.out.println(c1.getBrand());
System.out.println(c1.getPrice());
// 你有了 有参构造之后 你还要 set方法干嘛啊?
// 反正 构造方法可以赋值。
// 你不想要set了
// 你要充分了解一下 set方法的作用。
//1:赋值
// 2: 需求: 刚才那个 奔马 这个名字 我好像起错了 应该是 奔驹
// 假设此时 没有set方法。
//c1 = new Car("奔驹",299); // 你要这么做 就是把之前的那个车 报废掉。 重新造一辆车 九尾了改个名字
//set方法
c1.setBrand("奔驹");
}
}
今后我们要写一个标准的JavaBean类:
无参构造
全参构造
属性私有
setget +this
面向对象的三大特征: 封装 继承 多态。
封装:
1: private 提高安全性
2: 方法 提高了代码的复用性。
3: 封装数据 JavaBean类--作用用来封装数据的。
数据类型
基本类型
引用类型
数组
类
接口
类: 按照功能来划分
工具类: 这种类 里面 包含了大量的方法 每个方法里面都有明确的功能
这种类里面通常没有属性。
class Uitls {
public void show(){
}
public void method(){
}
....
}
测试类 :能够运行的类
class Demo {
public static void main(String[] args){
}
}
class Demo1 {
@Test
public void show(){
}
}
JavaBean类 :这种类里面 几乎全部都是属性, 每个属性都有private 并且 setget方法。
这种类 是用来封装数据用的。
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Demo {
public static void main(String[] args){
//数组
//int[] arr = new int[]{10,20,30};
int[] arr = new int[2];
arr[0] = 10;
arr[1] = 20;
//Student stu = new Student(13,"zhangsan");
Student stu = new Student();
stu.setAge(13);
stu.setName("张三");
}
}