学习08[面向对象]
什么是面向对象
-
面向过程
线性思维,步骤明确
-
面向对象
-
对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统
-
但是具体到微观操作,仍需要面向过程的思路去处理
-
-
OOP
-
本质:以类的方式组织代码,以对象的组织(封装)数据
-
抽象
-
三大特性
-
封装
-
继承
-
多态
-
-
认识论角度:先有对象后有类
对象是具体的事物,类是抽象的,是对对象的抽象
-
代码运行角度:先有类后有对象,
类是对象的模板
回顾方法并加深
-
方法的定义
-
修饰符
-
返回类型
//Demo01 类 用class修饰
public class Demo01 {}/*
修饰符 返回值类型 方法名(){
//方法体
return 返回值;
}
* */public String sayHello(){ return "Hello,world!";
}
public int max(int a ,int b){
return a>b?a:b;//三元运算符
} -
break和return的区别
-
break跳出switch,结束循环
-
return结束方法,返回一个结果
-
-
方法名——规范+见名知意
-
参数列表
-
参数类型
-
参数名
-
任意参数数量...
-
-
异常抛出
-
-
方法的调用
-
静态方法和非静态方法
//静态方法 static
//非静态方法 没有static-
静态方法之间引用
-
非静态方法需要实质化
public void say(){
System.out.println("学生说话了");
}
//非静态方法 实例化这个类 new
//对象类型 对象名 = 对象值
//new.Student()
Student student = new Student();
student.say(); -
-
方法之间的调用
a方法不可以引用b方法的原因:
a是静态
b是非静态
-
形参和实参
public static void main(String[] args) {
//形式参数和实际参数的类型要对应
int add =Demo03.add(1,2); System.out.println(add);
}
public static int add(int a,int b){
return a+b;
}
-
值传递和引用传递
-
值传递
两个结果都是1
//值传递
public static void main(String[] args) {
int a=1; System.out.println(a);//1
Demo04.change(a); System.out.println(a);//1
}
//返回值为空
public static void change(int a){
a = 10;
}-
引用传递
public class Demo05 {
//引用传递:对象 本质还是值传递
public static void main(String[] args) {
Person person = newPerson();
System.out.println(person.name);//null
Demo05.change(person); System.out.println(person.name);//秦疆
}
public static void change(Person person){ //person是一个对象,指向-->Person person = new Person();这是一个具体的对象,可以改变属性
person.name= "秦疆";
}
}
//定义了一个Person类,里面有一个属性:name
class Person{
String name;//默认值为null
} -
-
类和对象的关系
-
类是抽象的数据类型,对某一类事物整体描述或定义
-
对象是抽象概念的具体实例
创建和初始化对象
-
使用new关键字创建对象
-
使用new关键字创建的时候,除了分配内存空间以外,还会给创建好的对象进行默认的初始化(null/0)
-
一个项目应该只存在一个main方法
//类:抽象的,需要实例化 //类实例化后会返回一个自己的对象 //student对象就是一个Student类的具体实例 Student xiaoming = new Student();
-
类里面包括属性和方法
-
构造器
类中的构造器也称构造方法
-
必须和类的名字相同
-
必须没有返回类型,也不能写void
//一个类即使什么都不写,它也会存在一个方法 //显示的定义构造器 public Person(){ } -
-
构造器的作用
-
用来初始化值
-
使用new关键字,本质是在调用构造器
-
//有参构造:一旦定义了有参构造,无参构造就必须显示定义
public Person(String name){ this.name=name;
}
-
定义有参构造后,如果想使用无参构造,就要显示的定义一个无参构造
-
alt+insert创建构造器
-
有参构造
右键——Generate——Constructor
-
无参构造
右键——Generate——Constructor——选择select none
-
创建对象内存分析
小结
-
类与对象
类是一个模板,抽象,对象是一个具体的实例
-
方法
定义,调用
-
对象的引用
-
引用类型:八个基本类型
对象是通过引用来操作,栈引用堆
-
-
属性:字段Field,成员变量
-
默认初始化
数字:0 0.0
char:u0000
boolean:false
引用:null
-
修饰符 属性类型 属性名 = 属性值
-
-
对象的创建和使用
-
new
-
构造器 Person kuangshen = new Person( );
-
对象的属性kuangshen.name
-
对象的方法kuangshen.sleep( )
-
-
类
-
静态的属性 属性
-
动态的行为 方法
-
封装
-
高内聚
类的内部数据操作细节自己完成,不允许外部干涉
-
低耦合
仅暴露少量的方法给外部使用
-
数据的隐藏(信息隐藏)
通常应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问
-
属性私有,get/set
-
意义
-
提高程序的安全性,保护数据
-
隐藏代码的实现细节
-
统一接口
-
提高系统的可维护性
-
//private:私有 无法直接引用
private String name;//名字
//提供一些可以操作这些属性的方法
//提供一些public的get,set方法
//get获得这个数据
public String getName(){
return this.name;
}
//给这个数据赋值
public void setName(String name){
this.name=name;
}
//s1.getName().sout可以直接生成
//System.out.println(s1.getName());
//alt+insert:自动生成get和set
//右键——Generate——Constructor——Getter and Setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
继承
-
继承的本质是对某一批类的抽象
-
extends的意思是"扩展",子类是父类的扩展
-
继承是类和类的关系
-
一个为子类,一个为父类
-
子类继承父类,使用关键字extends来表示
-
在java中默认直接或者间接继承object类
-
ctrl+h:打开关系树?
-
Java中只有单继承,没有多继承
一个父亲可以有多个儿子,一个儿子不能有多个父亲
Super
-
//父类 public Person() { System.out.println("Person无参执行了"); }//子类 //隐藏代码:默认调用父类的无参构造 //super(); public Student() { System.out.println("Student无参执行了"); } -
注意点:
-
Super调用父类的构造方法,必须在构造方法的第一个
-
Super必须只能出现在子类的方法或者构造方法中
-
Super和this不能同时调用构造方法
-
-
vs this
-
代表对象不同
-
this:本身调用者这个对象
-
Super:代表父类对象的应用
-
-
前提不同
-
this:没有继承也可以使用
-
Super:只有在继承条件下才可以使用
-
-
构造方法不同
-
this();本类的构造
-
super();父类的构造
-
-
-
父类没有无参构造,子类也无法写无参构造
方法重写
-
重写都是方法的重写,和属性无关
-
需要有继承关系,子类重写父类的方法
-
方法名必须相同
-
参数列表必须相同
-
修饰符:范围可以扩大,但不能缩小
public>protected>default>private
-
抛出的异常:范围,可以被缩小,但不能扩大
-
-
子类和父类的方法必须一致,方法体可以不同
-
为什么需要重写?
-
父类的功能,子类不一定需要,或者不一定满足
-
-
O代表重载
-
Override重写
@Override//有功能的注释
-
自动生成重写快捷键:
右键——Generate——Constructor——选择
//静态方法和非静态方法区别很大
//静态static:方法的调用只和左边,即定义的数据类型有关
//非静态:重写,结果一样——>A A
public static void main(String[] args) {
A a = new A();
a.test();//A
B b = new A();//子类重写了父类的方法
b.test();//B
}
多态
-
即同一方法可以根据发送对象的不同而采用多种不同的行为方式
-
动态编译:类型
//一个对象的实际类型是确定的 //new Student(); //new Person(); //可以指向的引用类型就不确定了:父类的引用指向子类 Student s1 = new Student(); Person s2 = new Student(); Object s3 = new Student(); s2.run();//子类重写父类的方法,执行子类的方法 s1.run();
-
让可扩展性更强
-
注意事项:
-
多态是方法的多态,属性没有多态
-
父类和子类,有联系,类型转换异常
ClassCastException
-
存在条件:
①继承关系
②方法需要重写,子类重写父类方法
其中不能重写,无法实现多态的:
-
static方法,属于类,不属于实例
-
final常量
-
private方法
③父类引用指向子类对象
子类重写父类的方法,则执行子类的方法 father f1= new son( );
-
-
-
对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
//Student能调用的方法都是自己的或者继承父类的 Student s1 = new Student(); //Person 父类型,可以指向父类,但不能调用子类独有的方法 Person s2 = new Student();
instanceof
-
判断一个对象时什么类型
-
能不能编译通过:是否存在父子关系
System.out.println(x instanceof y)
//Object > String //Object > Person > Teacher //Object > Person > StudentObject object = new Student(); System.out.println(object instanceof Student);//true System.out.println(object instanceof Object);//true System.out.println(object instanceof Person);//true System.out.println(object instanceof Teacher);//false System.out.println(object instanceof String);//false
-
父类引用指向子类对象
Person person=student;
-
把子类转化为父类,向上转型
把父类转化为子类,向下转型,强制转换
-
类型之间的转化 父 子
//高-----------------低 Person obj = new Student(); //低到高直接转化,高到低强制转化 //想用子类方法可以强转化为子类 //student将这个类型转为Student类型,我们就可以使用Student类型的方法了 Student student = (Student) obj; student.go();
//最后两句可以简化为 ((Student) obj).go();
-
子类转化为父类,可能丢失自己本来的一些方法
static
-
变量
private static int age;//静态变量 多线程
private double score;//非静态变量
public static void main(String[] args) {
Student s1 = new Student(); System.out.println(Student.age); System.out.println(s1.age); System.out.println(s1.score);
}
-
方法
-
静态代码块
-
静态代码块只执行一次
匿名代码块赋初始值
-
静态导入包
import static java.lang.Math.random;
-
通过final被修饰的类没有子类
public final class Person {
抽象类
-
abstract修饰抽象类
//abstract抽象类
public abstract class Action {
//约束,有人帮我们实现
//abstract 抽象方法 只有方法名字,没有方法的实现
public abstract void doSomething();
}
//抽象类的所有方法,必须由继承它的子类实现,除非继承它的子类也是抽象的
public class A extends Action{
@Override
public void doSomething() {
}
}
-
Java的类是单继承,但是接口可以实现多继承
-
抽线类特点
-
不能new这个对象,只能靠子类去实现它:约束
-
抽象类里面可以写普通方法,抽象方法必须再抽象类里
-
-
抽象的抽象
接口
-
普通类:只有具体实现
-
抽象类:具体实现和规范(抽象方法)都有
-
接口:只有规范,自己无法写方法,约束和实现分离
-
接口就是规范,定义一组规则:如果你是汽车,则必须能跑
-
接口的本质是契约
-
利用接口实现多继承
public class UserServiceImpl implements UserService,TimeService{ } -
接口里面定义的属性都是常量
public static final
int age=99;
-
作用:
-
约束
-
定义一些方法,让不同的人实现
-
方法都是public abstract
-
常量public static final
-
接口不能被实例化,接口中没有构造方法
-
implements可以实现多个接口
-
必须要重写接口中的方法
-
N种内部类
-
外部类和内部类
//new 外部对象 Outer outer = new Outer(); //通过这个外部类来实例化内部类 //outer.new Inner(); Outer.Inner inner = outer.new Inner(); inner.getId();
-
//一个Java文件中可以有多个class类,但是只能有一个public class类 class A{ } -
局部内部类
-
public class Test {
public static void main(String[] args) {
//匿名内部化:
//没有名字初始化,不用将实例保存在变量中:Apple apple = new Apple();
new Apple().eat();
}
}
class Apple{
public void eat(){
}
}

浙公网安备 33010602011771号