面向对象
面向对象
什么是面向对象
面向过程:一部一部的,做完一条做下一条
面向对象:分类思想,比如做一件事情要分很多类,比如造一俩车,要有轮胎,发动机,玻璃。。。,分完类,变成很多小部分,在面向过程,将这小部分一步一步解决。
语句多了,我们将完成同样功能的相近的语句,聚到了一块儿,便于我们使用。于是,方法出现了!
变量多了,我们将功能相近的变量组在一起,聚到一起归类,便于我们调用。于是,结构体出现了!
再后来,方法多了,变量多了!结构体不够用了!我们就将功能相近的变量和方法聚到了一起,于是类 和对象出现了!
什么是类和对象
类:一个模板(抽象出的共有的特点)
对象:根据这个模板造出的具体事物
代码中 先有类后有对象
面向对象编程(Object-Oriented Programming, OOP)。
面向对象编程本质:以类的方式组织代码,以对象的方式封装数据
类=属性+方法(类是一个抽象的数据类型)
以这个类创建对象(实例化),这个对象的属性就有默认值,可以用对象修改自己的属性
static方法
静态方法 可以类名.方法名()调用,静态方法是属于类的,即静态方法是随着类的加载而加载的,在加载类时,程序就会为静态方法分配内存
非静态方法(不包含static) new 一个对象,对象名.方法名()调用,非静态方法是属于对象的,对象是在类加载之后创建的,可以调用非静态方法(不需要new 对象),也可以调用静态方法
在类中static方法只能调用static 方法(类名.方法(),因为在对象未存在时非静态方法也不存在,而静态方法自然不能调用一个不存在的方法。
或者在static中实例化一个对象(创建对象),用对象.方法()来调用没有包含static的方法
总结:类中方法中的调用,两个方法都是静态或者非静态都可以互相调用,当一个方法是静态,一个方 法是非静态的时候,非静态方法可以调用静态方法,反之不能。
静态代码块
static{
}
和类加载一起,之后是匿名代码块,和构造方法
创建与初始化对象
new关键字
Student s=new Student()
1创建了一个对象,分配内存,2调用构造方法,无参构造方法会把成员变量默认初始化,先默认初始化,后显示初始化,3把对象内存地址赋值给s变量
构造器(alt+insert在idea)
public Student(){
//修饰符+类名(可包含参数)
//在new Student()时会调用构造方法,如果该类有父类,会先调用父类无参构造方法,在构造方法第一行隐藏了super();
//super()或this()只能放在第一行,只能存在一个
构造器的作用:
1. 使用new创建对象的时候必须使用类的构造器
2. 构造器中的代码执行后,可以给对象中的属性初始化赋值
注意:
该类有参构造方法,无参构造方法会消失
}
一个类,默认有一个无参构造方法,如果有个有参构造方法,默人的无参构造方法会消失,要注意添加
左边是右边Penson类编译后的class文件,反编译的结果

有个有参构造方法,默人的无参构造方法会消失

构造器可以重载
package com.cwk.oop;
public class Person {
String name;
public Person(String name) {
this.name = name;
}
public Person() {
}
}
内存分析
package com.cwk.oop;
public class Application {
//启动类,一个项目不要每个类都写main方法,专门写一个启动类写main方法
public static void main(String[] args) {
Person person1 = new Person();
person1.name="小明";
System.out.println(person1.name);
person1.introduce();
}
}
package com.cwk.oop;
public class Person {
String name;
public Person(String name) {
this.name = name;
}
public Person() {
}
public void introduce(){
System.out.println("我叫"+name);
}
}

封装(数据的隐藏)
封装:该藏的藏,该漏的漏,电视和遥控,漏一个遥控操作电视
高内聚
类的内部数据操作细节自己完成,不允许外 部干涉
低耦合
类或方法的联系程度,仅暴露少量的方法给外部使用。
在代码中:属性私有(private 修饰属性),get set 为public 用于调用修改,私有的属性,在set中判断属性的范围如年龄有范围
private属性在该类中可以调用,在其他类只能靠那个类提供的public方法来使用与修改
package com.cwk.oop;
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>150||age<0){
System.out.println("age异常");
return;
}
this.age = age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
public void study() {
System.out.println(name + "爱学习");
}
}
package com.cwk.oop;
public class Application {
//启动类,一个项目不要每个类都写main方法,专门写一个启动类写main方法
public static void main(String[] args) {
Student student = new Student();
student.setName("小明");
student.setAge(180);
}
}
继承
类是对象的抽象,把类在抽象成各种类都要的部分 如猫,狗,可以抽象成动物
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
为什么需要继承?继承的作用? 第一好处:继承的本质在于抽象。类是对对象的抽象,继承是对某一批类的抽象。 第二好处:为了提高代码的复用性
JAVA中类只有单继承,没有多继承(只有一个爹,爹可以有很多孩子)! 接口可以多继承!
子类可以继承父类非私有的属性,方法,父类私有的,子类不可以继承(朕可以的,才是你的),public static 方法可以继承,不能被重写,父子都有相同的静态方法,靠引用的类型决定掉谁(Person p=new Student())p的引用类型是person,对象类型是Student
java中的每一个类都是"直接" 或者 "间接"的继承了Object类
this
意思:某个类创建的对象,this指向这个对象(代表这个对象),可以操纵这个对象
可以看到,打印出来地址一模一样

1.区分成员变量局部变量
public void setName(String name) {
this.name = name;
}
2调用类的其他方法(包括构造方法)
this(); this(参数)调用构造方法 this.方法名()调用其他方法
super和this
在普通方法中
首先extends,翻译为扩展比较好 是父类有的,都给了子类(子类有的就是父类给的,这两个是一样的,比如爸爸给孩子1000000,孩子有了这1000000,钱是不变的)

如果在son类中,加个money属性,钱就没有继承(不是重写,我反正凭感觉理解的),修改son.money不会影响super.money

package com.opp3;
public class Father {
public String name;
public int money=1000000;
}
package com.opp3;
public class Son extends Father {
public int money;
public void printName(){
System.out.println("this.name"+this.name);
System.out.println("super.name"+super.name);
}
public void printMoney(){
System.out.println("this.money"+this.money);
System.out.println("super.money"+super.money);
}
}
package com.opp3;
public class Application {
public static void main(String[] args) {
Son son = new Son();
son.printMoney();
}
}
super和this在构造方法中
在子类的构造方法中,会默认调用父类的无参构造方法,就像在子类的构造方法中调用super();
这个结果跟之前的钱一个道理


在son类,添加一个名字属性后,这种添加属性后,就不是继承的,结果自己name没有完成赋值



重写:
在继承的基础上,针对非静态方法,子类不需要父类的某些功能,或这个功能不够用,重写这个方法,来满足自己需求(比如父类是annimal 有一个方法move() 运动,子类有cat 和fish cat的move要重写为爬或跑,fish重写为游泳)
private 或static 或final修饰的方法不可以重写

对于静态方法,没有重写,类是什么(静态方法和类一起加载),就调用那个类的对应静态方法

多态
多态存在的条件 1. 有继承关系 2. 子类重写父类方法 3. 父类引用指向子类对象
作用:
方便方法的调用,减少重复代码
Animal pet=new Cat();
父类引用指向子类对象
pet可以调用Cat类重写的方法
pet=new Dog()
pet可以调用Dog类重写的方法,但只能调用Dog()继承或重写的方法Dog类新方法,需要强转类((Dog)pet)
instanceof
有继承关系就为true
抽象类
加了个abstract的类,有抽象方法和正常方法
抽象方法(abstract修饰的,有方法名,没方法体)子类继承后,必须重写,不然报错(一种约束),且抽象类还不能new(作为一种约束,去约束子类),存在构造器
static和abstract不能同时存在(static不能被重写(可以被继承),abstract必须重写)

接口
约束比抽象类还要强的约束
类:有方法的实现
抽象类:有抽象方法和类的实现
接口:只有抽象方法,不能有static,方法修饰发只能为public abstract(可以不写)
接口用interface定义,有implement 实现(可以实现多个接口与继承不同)
接口里面的变量都是常量 public static final当修饰符
实现接口的类必须重写接口的方法
package com.opp3;
public interface UserService {
void add();
void delete(String name);
int a=100;
}
package com.opp3;
public class UserServiceImpl implements UserService{
@Override
public void add() {
}
@Override
public void delete(String name) {
}
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
}
}
内部类
搞不懂。。。
浙公网安备 33010602011771号