对象类型 对象名 =对象值
对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统.但是,具体到微观操作,仍然需要面向过程的思路去处理.
本质 以类的方式组织代码,以对象组织封装
三大特性
封装
继承
多态
认知角度先有对象 再有类 对象 对象是具体的事物 类是抽象是对对象的抽象
代码运行角度先有类 后有对象 类是对象的模板
package 面向对象; //类 public class { public static void sa(){ System.out.println("你爹说话了"); } public void sb(){ System.out.println("我你爹"); } } xs01 zhangsan = new xs01(); //创建对象:“Zhangshan” zhangsan.sb(); //对象行为:对象自己发出行为修饰符
public 公共
protected 受保护的
private 私有
default 默认
静态方法 与非静态方法对象类型 对象名 =对象值
package 面向对象; import java.util.Scanner; public class demo02 { //静态方法 static public static void main(String[] args) { xs01.sa(); //非静态 // 实例化这个类 new xs01().sb(); xs01 xs01 = new xs01(); // 对象类型 对象名 =对象值 xs01.sb(); } }值传递
public class Demon05 { public static void main(String[] args) { int a=1; //值传递 System.out.println(a);//1 Demon05 demon05 = new Demon05(); demon05.o(a); System.out.println(a);//1 }public void o(int a){ a=23; } }引用传递
public static void main(String[] args) { // 引用传递 a1 a1 = new a1(); System.out.println(a1.name);//null Demon04 demon04 = new Demon04(); demon04.a(a1); System.out.println(a1.name); a1.name="很坏"; System.out.println(a1.name); } public void a(a1 b){ // b是一个对象,指向的———— a1 a1 = new a1();是一个具体的人,可以改变属性 b.name="钰钰"; } } class a1 { //类 类名a1 String name; //属性name }
类是一种抽象的数据类型 它是对某一类事物整体 描述/定义,但是并不能代表某一个具体的事物
动物 手机
对象是概念的具体实例
钰钰是人 张三是狗
创建对象使用new 关键字创建对象
会给对象分配一些默认的值与空间 以及对类中的结构器的调用
Demo01类
package 面向对象.Demon02; public class Demon01 { String name; int a;//属性 ;字段 //方法 public void xs(){ //this 代表着当前这个类 System.out.println(this.name+"学生在学习"); } }
package 面向对象.Demon02; //一个项目只有一个main方法 public class app { public static void main(String[] args) { //类 抽象的 实例化 //类实例化会返回一个自己的对象 // dx对象是Demon类的具体实例 Demon01 dx = new Demon01(); System.out.println(dx.name);//name 默认是null dx.name="王晨狗贼"; System.out.println(dx.name); System.out.println(dx.a);//a 默认0 dx.a=3; System.out.println(dx.a);//3 Demon01 ds = new Demon01(); System.out.println(ds.name);//null System.out.println(ds.a);//0 } }结构器
类中构造器 也称为构造方法 是在进行创建对象的时候必须调用的 并且构造器 有以下俩特点
必须 和类的名字相同
必须没有返回类型 也不能写void
package 面向对象.Demon02; public class Demon02 { String name; //一个类什么都不写 它也会存在一个方法 // 显示定义构造器 // 显示化初始值 // 使用new关键字 必须要有关键字 本质是在调用构造器 int a; public Demon02() { } //快捷键 alt +ins //有参构造 一但定义了有参构造无参必须显示定义 public Demon02(String name) { this.name = name; } public Demon02(int a) { this.a = a; } public Demon02(String name, int a) { this.name = name; this.a = a; } } //package 面向对象.Demon02; // 一个项目只有一个main方法 //public class app { // public static void main(String[] args) { // //new 实例化了一个对象 // Demon02 ds = new Demon02(); null // System.out.println(ds.name); // Demon02 dx = new Demon02("牛逼"); // System.out.println(dx.name); 牛逼 // // } //}
构造器
和类名相同
没有返回值
作用
new 的本质是调用构造方法
初始化对象的值(初始化成员变量的值)
注意点
定义了有参构造之后 如果向使用无参构造 需要显示一个无参构造
pet p = new pet(); pet p; 栈 p = new pet();堆类与对象的小结
-
类于对象
类是一个模块:抽象,对象是一个具体的实例
-
方法
定义,调用
-
对应的引用
引用类型: 基本类型(8)除了八大类型 的都可以叫引用类型
对象是通过引用来操作的:栈——堆(地址)
-
属性:字段field 成员变量
默认初始化:
数字:0
char:u000
bolean:false
应用:nulll
修饰符 :属性类型 属性名 =属性值
-
对象的创建和使用
必须使用new 关键字创建对象 ,构造器 快捷键Alt+ins
pet p = new pet();
对象的属性 p.name
对象的方法 p.et()
-
类
静态的属性 属性
动态的行为 方法
类的初始化顺序父类的静态字段——>父类静态代码块——>子类静态字段——>子类静态代码块——>
父类成员变量(非静态字段)——>父类非静态代码块——>父类构造器——>子类成员变量——>子类非静态代码块——>子类构造器
高内聚,低藕合
高内聚就是类的内部数据操作细节自己完成,不允许外部干涉
低藕合仅暴露少量方法给外部使用
this.属性名称
指的是访问类中的成员变量,用来区分成员变量和局部变量**(重名问题)**
private int mon= 1_000; public void setMon(int on) { mon = on; } //———————————————————————————————————————— public void seMon(int mon) { this.mon = mon; }
属性稀有 get/set
alt+insert 快捷键 自动生成 set 还在get
get 获得这个属性
set给这数据赋值
优点
1.提供程序的安全性.保护数据
2.隐藏代码的细节
3.统一接口
4.提高了系统的可维护信
package 面向对象.封装; public class Add01 { public static void main(String[] args) { Student d = new Student(); d.id=23; System.out.println(d.id); d.setName("吴彦祖"); System.out.println(d.getName()); d.setNl(90); System.out.println(d.getNl()); } } //--------------- //类 package 面向对象.封装; //类 private 私有 public class Student { //学号 public int id; // 名字 private String name; // 性别 private char xb; // 年龄 private int nl; //提供一些可以操作这个属性的方法 // 提供一些public的get,set方法 // get 获得这个属性 // set给这数据赋值 // get获得这个值 public String getName() { return this.name; } // set 设置值 public void setName(String name) { this.name=name; } //alt+insert 快捷键 自动生成 set 还在get public int getNl() { return nl; } public void setNl(int nl) { if (nl>100||nl<0){//不合法 this.nl = 0; }else { this.nl = nl; } } }继承 extends
JAVA中类只有单继承,没有多继承! 一个儿子只能有一个爸爸
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
子类和父类之间,从意义上讲应该具有**“is a”**的关系.
在同一个包里私有的东西继承 无法访问
不在同一个 包里私有和默认的 无法访问final是断子绝孙修饰符(常量) 也无法继承**
快捷键 Ctrl+h 继承树
在Java 中所有的类,都默认直接或者间接继承object
package 面向对象.继承; //人 父类 public class Person { public void say(){ System.out.println("说了一句话"); } private int mon= 1_000; public int getMon() { return mon; } public void setMon(int mon) { this.mon = mon; } } /-------------------------继承-------------------- package 面向对象.继承; //老师 is 人 子类 //子类继承父类就会拥有父类的全部方法 public class teachar extends Person{ } //------------------------main------------------ package 面向对象.继承.app; import 面向对象.继承.Person; import 面向对象.继承.Student; import 面向对象.继承.teachar; public class app { public static void main(String[] args) { teachar person = new teachar(); person.say(); System.out.println(person.getMon()); person.setMon(233); System.out.println(person.getMon()); } }
先父及子,静态先行
Person静态代码块—>Student静态代码块—>Person{}、Person构造器—>Student{}、Student构造器
package 面向对象.继承.继承1; //人 父类 public class per { protected String name="chenshuyu"; public per(){ System.out.println("per 的无参构造器执行"); } public void pr(){ System.out.println("陈淑钰非常的帅“父类方法”"); } } //---------------------子--------------- package 面向对象.继承.继承1; //学生 is 人 子类 public class St extends per { public String name = "yuan"; public St() { // 隐藏了一个代码 super()执行了父类的无参构造器 //写 super() 调用父类构造器,比心在子类构造器的第一行 // super(); this("大大"); // 调用有参构造器,比心在构造器函数第一行 System.out.println("St 的无参构造器执行"); } public St(String name) { System.out.println("2" + name); } public void pr() { System.out.println("陈淑钰非常的帅“类中”"); } public void test() { pr(); this.pr(); super.pr(); } public void test(String name) { System.out.println(name);//方法里的 System.out.println(this.name);//当前类里的 System.out.println(super.name);//父类 } } //----------------启动---------------- package 面向对象.继承.继承1; public class app1 { public static void main(String[] args) { St st = new St(); St st1 = new St("666"); System.out.println(st1.name); } } //---------------------结果---------- //per 的无参构造器执行 //2大大 //St 的无参构造器执行 ///per 的无参构造器执行 //2666 //yuansuper vs this
super注意点: (父类的)
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中!
- super和 this 不能同时调用构造方法!
vs this:(当前类)
代表的对象不同:
this:本身调用者这个对象super:代表父类对象的应用前提
this:没继承也可以使用
super:只能在继承条件才可以使用构造方法
this();本类的构造super():父类的构造!
1.生命周期不同。静态方法的生命周期跟相应的类一样长,静态方法和静态数据成员会随着类的定义而被分配和装载入内存中。一直到线程结束,静态属性和方法才会被销毁。(类创建的是时候 静态方法也创建了 销毁是一起销毁的 这俩是捆绑的 一条船上的蚂蚱)
非静态方法的生命周期和类的实例化对象一样长,只有当类实例化了一个对象,非静态方法才会被创建,而当这个对象被销毁时,非静态方法也马上被销毁。
(对象创建的是时候 非静态方法也创建了 销毁是一起销毁的 这俩也是是捆绑的 一条船上的蚂蚱)
2.调用方式。静态方法可以直接调用,类名调用和对象调用。但是非静态方法只能通过对象调用。
package 面向对象.静态; import com.sun.org.apache.bcel.internal.generic.NEW; public class App { static int a; private int b; public static void jt(){ System.out.println("静态"); } public void fjt(){ System.out.println("非静态"); } public static void main(String[] args) { App a1 = new App(); System.out.println(a1.a); System.out.println(App.a);//静态类名直接调用 System.out.println(a1.b); //调用方法 new App().fjt();//非静态new App app = new App(); App.jt();//静态类名直接调用 } }静态代码块
作用可以赋初始值
第一个执行 只是执行一次
package 面向对象.重写.类型转换; public class Person { {//第2个 System.out.println("代码块"); } static {//第一个执行 只是执行一次 作用可以赋初始值 System.out.println("静态代码块"); } public Person() {//第3个 System.out.println("构造器"); } public static void main(String[] args) { Person person = new Person(); System.out.println("---------------------"); Person person2 = new Person(); } }重写
为什么需要重写 父类的功能 子类不一定需要 或者不一定满足
重写 :需要有继承关系 子类重写 父类的方法(不是属性)!
1.方法名必须相同
2**.参数列表必须相同** (不然就是重载了)
3.修饰符:范围可以扩大但是不能缩水:public 公共>protected 受保护的>default 默认>private 私有
4.抛出的异常:范围 可以被缩小。但不能被扩大
重写 子类的方法和父类必须一致:方法体不同
package 面向对象.重写; //启动 public class app { public static void main(String[] args) { // 动态方法的调用之和左边,定义的数据集类型有关 // 静态方法调用只和左边定义的有关 // 非静态方法 重写 A a = new A(); a.test();//动态 A=>tese //静态 A=>tese B b = new A(); // 动态 父类的引用指向了A b.test();// 动态 B=>tese } } //----------------------父类----------- package 面向对象.重写; public class B{ public void test(){ System.out.println("B=>tese"); } } //-----------子类---------------------- package 面向对象.重写; //重写都是方法的重写和属性无关 public class A extends B { @Override//注解 有功能的注解 //Override 重写 //静态方法 有 static 的方法 public void test() { System.out.println("A=>tese"); } }多态
父类 对象名=new 子类;
即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
(同一个引用类型 使用不同的实例而执行不同的操作)
三要素
具有 继承关系 的父类和子类
子类 重写父类 方法
使用父类的引用指向子类的对象
实现多太的两种方式
使用父类作为 形参实现多太(传递的是父类或子类对象)
使用父类作为方法返回值实现多态(返回的是父类或者子类对象)
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类,有关系的类)
方法的多态性:重载与覆写
|-重载:同一个方法名称,根据不同的参数类型及个数可以完成不同的功能。
|-覆写:同一个方法,根据操作的子类不同,所完成的功能也不同。
注意事项
多态是方法的多态 属性没有多态
父类和子类有联系 (类型转换异常!ClassCastException!)
存在的条件:继承关系 方法需要重写 父类引用指向子类(父类 a1=new 子类)
不能多态的
static 方法 属于类 不属于实例
final 是常量 无法继承:
private 方法 无法继承:
静态方法是类的方法,而非静态是对象的方法
多态的访问方式:
(1)成员变量
编译看左边,运行看左边
变量是没有重写的是类独有的
(2)成员方法
编译看左边,运行看右边
非静态的方法是对象的方法 通过对象调用
(3)静态方法
编译看左边,运行看左边
总结 静态方法是类的方法,而非静态是对象的方法
(1)成员变量
编译看左边,运行看左边
package com.itheima; public class Demo1_2 { public static void main(String[] args) { Dad dad = new Kid(); System.out.println(dad.num); } } class Dad{ int num = 20; } class Kid extends Dad{ int num = 10; } 输出结果为:20
父类引用指向子类对象,父亲类和儿子类中都有成员变量,变量不像方法一样有重写,变量是没有重写的概念的,所以运行的是父类方法的成员变量。如果父类中没有这个成员变量,程序会出现编译错误。
(2)成员方法
编译看左边,运行看右边
package com.itheima; public class Demo1_2 { public static void main(String[] args) { //父类引用指向子类对象 Dad dad = new Kid(); dad.method(); } } class Dad{ public void method() { System.out.println("我是父类方法"); } } class Kid extends Dad{ public void method() { System.out.println("我是子类方法"); } } 输出的结果为:我是子类方法
因为成员方法是可以重写的,所以会执行子类的方法。但是如果父类中没有method()方法,编译器会报错。
(3)静态方法
编译看左边,运行看左边
package com.itheima; public class Demo1_2 { public static void main(String[] args) { //父类引用指向子类对象 Dad dad = new Kid(); dad.method(); } } class Dad{ public static void method() { System.out.println("我是父类静态方法"); } } class Kid extends Dad{ public static void method() { System.out.println("我是子类静态方法"); } } 输出结果是:我是父类静态方法
分析:使用变量去调用静态方法,其实相当于变量类型的类名去调用,也就是Dad.method(),所以运行的是父类里面的静态方法。如果父类没有静态方法,编译报错。
package 面向对象.多态; public class app { public static void main(String[] args) { // 对象的实际类型是确定的 // new Student(); // new Person(); // 可以指向的引用类型是不确定的:父亲的引用指向子类 // Student 调用的方法都是自己的或者是继承的 Student student = new Student(); Person student1 = new Student();//父类 //person 可以指向子类 .但是不能调用子类读独有的方法 Object student2 = new Student(); //Object 祖宗类 // 对象能执行那些方法.主要看对象左边的类型 和右边关系不大 student1.run();//子类重写了父类的方法 执行子类的方法 student.run(); } } //-------------------父-------------- package 面向对象.多态; public class Person { public void run(){ System.out.println("run"); } } //--------------------子------------------- package 面向对象.多态; public class Student extends Person { public void run(){ System.out.println("son"); } }instanceof
instanceof(类型转换)引用类型
(类型转换)引用类型)实例
System.out.println(X instanceof Y) 判断 x与y是否有父子关系 如果有则为 true 如果没有则为false
package 面向对象.重写.Instanceof; import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; import java.util.Scanner; public class App { public static void main(String[] args) { // Object> Person> Student //Object> Person> Teacher //Object> String Object Object1 = new Student(); //System.out.println(X instanceof Y) 判断 x与y是否有父子关系 如果有则为 true 如果没有则为false System.out.println(Object1 instanceof Student);//true System.out.println(Object1 instanceof Person);//true System.out.println(Object1 instanceof Object);//true System.out.println(Object1 instanceof Teacher);//false Object> Person> Teacher System.out.println(Object1 instanceof String);//false Object> String System.out.println("----------------------------"); Person Person1 = new Student(); System.out.println(Person1 instanceof Student);//true System.out.println(Person1 instanceof Person);//true System.out.println(Person1 instanceof Object);//true System.out.println(Person1 instanceof Teacher);//false } }类型之间的转化:基本类型转换
父子类对象的转换。
向上转型:子类对象变为父类对象,格式:父类 父类对象 = 子类实例,自动;
向下转型:父类对象变为子类对象,格式:子类 子类对象 = (子类)父类实例,强制。
方便方法调用 建设重复的代码
基本类型转换 高低64 32 16 8 高转低 强转 低转高 自动
package 面向对象.重写.类型转换; public class Person { } package 面向对象.重写.类型转换; import 面向对象.重写.A; public class App { public static void main(String[] args) { //类型之间的转化:基本类型转换 高低64 32 16 8 高转低 强转 低转高 自动 Person s1 = new Student();//自动转 //s1将这个吧对象转换成Student类型 就可以用 Student类型的方法了 ((Student)s1).son(); Student s2 = new Student(); Person P1=s2; ((Student)P1).son();//子类转换父类 后丢失父类没有的方法 //低(子)转高(父)时,由于子已经继承了父的所有,所以删去属于自己的后自然而然就可以转化问父类的;而父想要转子,则需要重新开辟只属于子的空间,则需用强制转换 } } //---------------------父Person--------------------- package 面向对象.重写.类型转换; public class Person { } //--------------------子Student-------------------- package 面向对象.重写.类型转换; public class Student extends Person{ public void son(){ System.out.println("son"); }} //-----------------子Teacher------------- package 面向对象.重写.类型转换; public class Teacher extends Person{ }抽象类
抽象类的所有方法继承了它的子类 都必须实现它的方法 爸爸、爷爷的靠不住~~孙子来顶住
extends 单继承 (接口可以多继承)
特点 不能new 只能靠 子类去实现 (约束)
抽象类里面 可以写普通方法
抽象方法必须在抽象类中
package 面向对象.抽象类; //abstract抽象类 public abstract class Action { //约束~有人帮我们约束 public void doSome(){ } // 抽象方法 只有方法的名字 没有方法的实现 public abstract void doSme(); }
package 面向对象.抽象类; //抽象类的所有方法继承了它的子类 都必须实现它的方法 爸爸、爷爷的靠不住~~孙子来顶住 //extends 单继承 (接口可以多继承) public class A extends Action{ @Override public void doSme() { } // 特点 不能new 只能靠 子类去实现 约束 // 抽象类里面 可以写普通方法 // 抽象方法必须在抽象类中 // 抽象的抽象 约束 }接口
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有!
接口:只有规范!自己无法写方法专业的约束!约束和实现分离:面向接口编程
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能….”的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你好人,则必须干掉坏人;如果你是坏人,则必须欺负好人。
**接口的本质是契约,**就像我们人间的法律一样。制定好后大家都遵守。
声明类的关键字是class,声明接口的关键字是interface
1.约束
2,定义一些方法 让不同的人实现
3.类 接口中的所有定义都是抽象的 public abstract
4.常量 //常量~public static final
5,接口不能被实例化 .接口没有构造方法
6.interface可以实现多个接口
7.必须重写接口的方法
package 面向对象.接口; public interface UserService { //常量~public static final int AGE=99; //接口中的所有定义都是抽象的 public abstract void add(String name); void delete(String name); void update(String name); void query(String name); } //--------------- package 面向对象.接口; public interface TimeService { void timar(); } //------------------- package 面向对象.接口; //类实现接口 implements //实现了接口的类 就需要重写接口的方法 //多继承 利用接口 实现多少继承 public class UserserviceImpl implements UserService,TimeService{ @Override public void timar() { } //快捷键 Ctrl+i @Override public void add(String name) { } @Override public void delete(String name) { } @Override public void update(String name) { } @Override public void query(String name) { } }内部类
内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。
1.成员内部类
⒉静态内部类
3.局部内部类
4.匿名内部类
匿名类
package 面向对象.内部类; public class 匿名类 { public static void main(String[] args) { new s().id(); // ad ad = new ad() new ad(){ @Override public void diao() { } }; } } class s{ public void id(){ System.out.println("1"); } } interface ad{ public void diao(); }
局部内部类
package 面向对象.内部类; public class 局部内部类 { public void id(){ // 局部内部类 class in{} } }
package 面向对象.内部类; public class 成员内部类 { private int id; private void id1() {} public void ouy() { System.out.println("这是外部类方法");} class inner { public void in() { System.out.println("这是内部类方法");} // 获得外部类id私有属性和方法 public void getid(){ id=10; System.out.println(id);}} public static class inner1 { public void in1() { System.out.println("这是静态内部类方法"); }} }//一个java类中只能有一个public class 但是有n个calls class a{}
abstract
java的基本数据类型和引用数据类型的区别
基本类型变量存放的是变量值
引用数据类型的变更了存放的是变量的引用(地址)