目录
面向对象
概述
重要知识点列表:
-
类与对象
-
构造方法
-
访问权限
-
继承
-
多态
-
抽象与接口
-
内存分析
面向对象与面向过程
面向过程:侧重过程
优点:简单
缺点:维护性差
面向对象:
优点:可拓展性非常强,维护成本低
缺点:上手难
类与对象
类:属性:这一类事物具有的共同属性(成员变量来描述)(成员变量是直接写在类中的变量)
方法:这一类事物共同执行的功能
对象:用类创建的某一个具体的是东西
成员方法:不写static就是成员方法(非静态方法)
public class Car { //在类中的变量:成员变量 String color; int speed; int seat = 5; public void run(){ System.out.println("车在跑"); } public static void main(String[] args) { // //在方法中的变量:局部变量 // int a = 10; Car c = new Car(); // 创建 (引用的过程) // run(); //不能直接调用 c.run(); c.color = "绿"; c.speed = 120; c.seat = 5;
* 创建一个对象的格式 *:类 引用 = new 类();
补充内容:
-
成员变量与及局部变量
//在类中的变量:成员变量 String color; int speed; public void run(){ System.out.println("车在跑"); } public static void main(String[] args) { // //在方法中的变量:局部变量 // int a = 10;
-
两种数据类型
基本数据类型:8种
引用数据类型:String以及所有自定义类
权限管理
修饰符 | 同一个类中 | 同一个包中的类(不管有无继承关系) | 不同包中的子类 | 不同包中的无关类 |
---|---|---|---|---|
private | 可以 | |||
default | 可以 | 可以 | ||
protected | 可以 | 可以 | 可以 | |
public | 可以 | 可以 | 可以 | 可以 |
this关键词
在调用c时,run()方法中this接受的对象与c保持一致;
-
在调用方法的时候。Java会自动将对象传递给方法,在方法中由this关键词来接受
this关键词的应用
this 随动:当前类的对象
package com.oop_new; public class Car2 { String color; //直接定义在类中:成员变量 int seat = 5; int speed ; public void run(){ //获取到车的颜色与速度 System.out.println(this.color+"的车会跑"+this.speed+"码这么快"); } public static void main(String[] args) { Car2 c = new Car2(); //车中的属性就是类中定义好的成员变量 c.color ="yellow"; c.speed = 120; c.run(); //在调用方法的时候。Java会自动将对象传递给方法,在方法中由this关键词来接受 } } 运行结果: yellow的车会跑120码这么快 Process finished with exit code 0
this区分成员变量与局部变量
public class Car2 { String color; int seat = 5; int speed ; public void fly(){ System.out.println(this.color+"的车会飞"); } public static void main(String[] args) { Car2 c = new Car2(); c.color="绿色"; c.fly(); } } //绿色的车会飞
public class Car2 { String color; int seat = 5; int speed ; public void fly(String color){ System.out.println(color+"的车会飞"); } public static void main(String[] args) { Car2 c = new Car2(); c.color="绿色"; c.fly("black"); } } //black的车会飞
public class Car2 { String color; int seat = 5; int speed ; public void fly(String color){ System.out.println(this.color+"的车会飞"); } public static void main(String[] args) { Car2 c = new Car2(); c.color="绿色"; c.fly("black"); } } //绿色的车会飞
public class Car2 { String color; int seat = 5; int speed ; public void fly(String color){ System.out.println(this.color+"的车会飞在"+color+"的云彩里"); } public static void main(String[] args) { Car2 c = new Car2(); c.color="绿色"; c.fly("black"); } } //绿色的车会飞在black的云彩里
构造方法
在创建对象的时候自动调用的方法:
语法:
pubic 类名(传参){
}
注意:
-
没有返回值
-
在new的时候,自动调用构造方法
-
Java会自动赠送每一个类一个构造方法(无参)
-
如果自己定义了构造方法,Java就不再赠送
最大的意义:在创建对象的时候给对象设置属性信息
public class Car3 { public Car3(String color,int speed){ //显式定义构造方法且传参 System.out.println("调用构造方法啦"); //设置属性信息 this.color = color; this.speed = speed; } String color ; int speed ; int seat = 5 ; public void run(){ System.out.println(this.color+"颜色的车在跑"); } public static void main(String[] args) { Car3 c0 = new Car3("绿",120); // c0.color ="绿"; // c0.speed =120; Car3 c1 = new Car3("红",180); // c1.color ="红"; // c1.speed =180; c0.run(); c1.run(); } }
构造方法的重载
package com.oop_new; public class demo04 { String name; String waihao; int age; String bangpai; public demo04(String name,int age ,String bangpai){ this.age= age; this.bangpai =bangpai; this.name = name; } public demo04(String name,String waihao,int age ,String bangpai){ this.age= age; this.bangpai =bangpai; this.name = name; this.waihao =waihao; } public static void main(String[] args) { //大侠一号 demo04 dx = new demo04("吴磊","吴老狗",12,"青龙帮"); //大侠二号 demo04 dx2 = new demo04("王小波",24,"白虎帮"); } }
其中
public demo04(String name,String waihao,int age ,String bangpai){ this.age= age; this.bangpai =bangpai; this.name = name; this.waihao =waihao; }
可改写为:
public demo04(String name,String waihao,int age ,String bangpai){ this(name,age,bangpai); //this可看作一个方法,调用本类中的其他构造方法 this.waihao = waihao;
final
-
final 修饰的变量不能被改变,被称为常量
-
final 修饰的方法不能被重写
-
final修饰的类不能被继承
总结:不可变
继承
-
关键词:extends
-
两个类之间的关系 子类(派生类)是父类(基类)的拓展,一定注意不是子集关系
-
只有单继承 (一个子类只有一个父类),没有多继承
子类会拥有父类的全部符合权限的方法与内容!
在Application类中,对student类进行实例化
但是student类中并没有定义say()方法,是继承了Person父类中的方法
什么时候使用? is a , 是...的一种
但是
注意权限,在继承时尽量使用public方法
上图中 private 修饰(属性私有)后,子类并未继承父类
public class Person { private int money = 10000000; //属性私有 public void say(){ System.out.println("说了一句话"); } //封装的思想,给予get set方法 public int getMoney(){ return money; } public void setMoney(int money){ this.money= money; } }
object类
所有的类都默认直接或间接继承object类(就算不显式定义继承object类)
变量访问特点
-
在一个方法中,访问变量时,优先访问方法内部的变量,再去寻找本类中变量,没有的话再去查找父类
-
方法内部——>本类——>父类
-
但是可以使用this与super关键词实现自己的需求
super方法/this方法
super方法的使用
运行结果
public void test(String name){ System.out.println(name); //这一个name 指代的是test方法传入的参数 System.out.println(this.name); //this 这一个 name 指代的是这个类里面的定义的属性 System.out.println(super.name); //super表示继承了父类中的name属性
继承与构造方法
现象描述
-
测试类(Application)中:new了一个student(子类)的对象,随即调用了student和person中的构造方法
-
注意是先调用了person类中的方法,再调用了student中的方法
解释
子类在调用自己的构造方法(有参或者无参)时,会默认在构造方法第一行运行父类的无参构造方法!
所以,父类中不能只有一个有参构造!!!
当然,也可以考虑在子类的构造方法中显式用super(参数);调用父类的有参构造。
-
隐藏了super()方法,每一个子类的构造方法第一行都默认是super()——无参; 若显式定义super(),必须放在第一行
这样做的原因:
-
子类默认继承父类中的数据,可能还会使用父类中的数据;所以在子类初始化的时候,一定要完成父类数据初始化
注意事项
问题一
-
super()发现报错了
-
规定在显式调用父类的无参构造(即写出super();),放在子类构造器的第一行
问题二
在一个类中,写了有参构造之后,系统赠送的无参构造消失
并且父类无参构造消失后,子类也无法进行无参构造
public class Person { public Person(String name){ //写了有参构造后,系统赠送的无参构造消失 System.out.println("person无参执行了"); }
问题三
super(参数列表)方法仍可进行有参调用!
-
将super(参数列表)方法用在子类的有参构造中,如果父类的有参构造方法是Public权限的,就可以实现从父类的有参构造器中的参数列表传递(继承)到子类中
如:
父类:
public class Father{ private int age; private String name; public void Father(){ System.out.println("这是父类无参构造") } public void Father(String name,int age){ this.name=name; this.age=age; System.out.println("这是父类有参构造,参数为"+name+"and"+age) } }
子类:
public class Son extends Father{ public void Son(String name,String age){ super(name,age); //这里本来想用父类中的参数,但是由于父类中的变量私有,无法直接访问可 以用super()方法间接继承参数列表 } }
问题四
利用获取器与构造器方法重载构造方法
父类:
public class Father{ private int age; private String name; public void Father(){ System.out.println("这是父类无参构造") } public void Father(String name,int age){ this.name=name; this.age=age; System.out.println("这是父类有参构造,参数为"+name+"and"+age) } 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; } }
子类:
public class Son extends Father{ public void Son(String name,String age){ setAge(age); setName(name); //这里本来想用父类中的参数,但是由于父类中的变量私有,无法直接访问可 以使用设置器方法调用父类方法 } }
问题四
总结
super注意点:
-
super调用父类构造器,只能放在子类构造器的第一行
-
super必须只能出现在子类的方法或者构造方法中
-
super与this不能同时调用构造方法
super vs this
-
代表对象:this为本身调用,super代表父类对象的引用
-
使用情况:this没有继承前提也能使用
-
构造方法:this()本类的构造,super()父类的构造
构造器中使用父类内容的时候一定要注意是不是public!
抽象
现实中不存在的东西
在Java中,只声明,不实现
定义与概念
public abstract class Animal { //类中有抽象方法,类也必须为一个抽象类 //抽象方法abstract,直接用;结尾,没有方法体 public abstract void eat(); }
特点
-
abstract ; 无方法体
-
抽象类不可以创建对象(实例化),但是也可以参照多态的方式,通过子类对象实例化对象(抽象类多态)
-
抽象类的子类必须重写父类中的抽象方法(子类中的方法不是成为抽象方法 ),否则,子类也必须是抽象类
-
由于第三点特点,通过抽象可以强制的要求子类中有哪些方法
-
抽象类中可以有正常方法,不一定全为抽象方法(接口全是)
-
抽象类中可以有成员变量(常量也可以),非抽象方法
-
可以有带参构造与无参构造(虽然不能直接实例化,可以间接)
public abstract class animal { public animal() { System.out.println("抽象类的构造方法调用了"); } public abstract void m(); }
public class animalImpl extends animal{ @Override public void m() { System.out.println("重写的抽象方法调用了"); } }
public class demo { public static void main(String[] args) { animal a = new animalImpl(); a.m(); } }
输出:
抽象类的构造方法调用了 重写的抽象方法调用了
接口
接口的概念与定义
-
接口实际上是一种特殊的抽象类
-
接口中所有的方法都是抽象方法
-
接口使用interface来声明(接口不是类)
// 接口中所有的方法都是抽象方法,可以省略abstract //接口中所有的方法都是公开的的,可以省略public public interface jiekou { public abstract void getMoney(); }
接口的代码特点
-
接口中所有的方法都是抽象方法,可以省略abstract
-
接口中所有的方法都是公开的的,可以省略public
-
接口中所有变量都是全局静态变量 public static final
-
所有变量都是最终变量(前用fina修饰)
所以,可改写为
` // 接口中所有的方法都是抽象方法,可以省略abstract //接口中所有的方法都是公开的的,可以省略public public interface jiekou { public abstract void getMoney(); }
接口的实现
-
能继承接口的只能是接口
-
接口与类之间只能是实现关系 implements(类似于继承关系)
在实现关系后,必须要重写抽象方法
接口与继承的联系
-
类只能单继承,接口支持多实现
-
接口同样 具有多态性
接口的作用
把很多不相关的内容进行整合
成员变量初始值
Java中所有的变量必须先声明后赋值,才能使用;
Java的成员变量在创建对象的时候,都会执行一次初始化操作,都会给一个默认值
byte,short,int,long,float,double 默认值都为零 char 默认值为编码位置为0的那个字符 Boolean 默认值为false String,自己定义的类 默认值都为null
equals与==
作用
== 判断左右两边的数据是否一致
equals :object类提供的一个方法,用来判断两个对象是否相等
equals的特点——重写
-
两者相似,但是equals是祖宗类中的方法,可以重写以满足我们的需求
public class Cat { String color; String name; public Cat(String name, String color){ this.name = name; this.color = color; } public static void main(String[] args) { Cat c1 = new Cat("小花","红色"); Cat c2 = new Cat("小花","红色"); System.out.println(c1==c2); //输出false,默认的判断的是两个对象的内存地址是否一致,很少将 ==用在对象判断上,而用在基本数据类型上 System.out.println(c1.equals(c2)); //输出false,默认调用的是object类中的equals方法,结 果不满意,对父类方法进行重写 } }
对object 父类中的方法进行重写,以满足猫的颜色相同即认为为相同
public class Cat { String color; String name; public Cat(String name, String color){ this.name = name; this.color = color; } public boolean equals(Cat c){ //对父类方法重写,实现两个对象的对比相等 if (this.color==c.color){ //单纯的写自己想实现的逻辑 return true; }else{ return false; } } public static void main(String[] args) { Cat c1 = new Cat("小花","红色"); Cat c2 = new Cat("小花","红色"); System.out.println(c1==c2); //输出false,默认的判断的是两个对象的内存地址是否一致,很少将==用在对象判断上,而用在基本数据类型上 System.out.println(c1.equals(c2)); //输出false,默认调用的是object类中的equals方法,结果不满意,对父类方法进行重写 } }
注意:字符串类型
public class test01 { public static void main(String[] args) { String str1 ="xiaohong "; String str2 ="xiaohong "; System.out.println(str1 == str2); //true System.out.println(str1.equals(str2)); //true } }
字符串类型特殊:str2并未指向第二个内存空间,而是指向了str1的内存空间
所以str1 与str2 的内存空间也一致,即str1 与 str2 完全相同
public class test01 { public static void main(String[] args) { // String str1 ="xiaohong "; // String str2 ="xiaohong "; // // System.out.println(str1 == str2); //true // System.out.println(str1.equals(str2)); //true String str3 = new String("杠"); String str4 = new String("杠"); System.out.println(str3 == str4); //false,双等判断的是地址,new的时候,相当于 开辟了一个空间,来存放对象(str1和str2),两 个对象的空间都指向存有字符串"杠"的内存空 间,但是两个对象的内存位置不一样 System.out.println(str4.equals(str4)); //true,String类中是重写了object类中的 equals方法,现在调用的是String类中的 equals方法,作用即为判断两个字符串的内容是 否一致 } }
-
字符串的判断用equals
以下为简单应用:
import java.util.Scanner; public class test02 { public static void main(String[] args) { String username = "admin"; String password = "123"; Scanner input = new Scanner(System.in); System.out.println("请输入用户名:"); String uname = input.nextLine(); System.out.println("请输入密码:"); String pass = input.nextLine(); if (username.equals(uname) && (password.equals(pass))){ System.out.println("登陆成功"); }else{ System.out.println("登陆失败"); } } }
object
万物皆对象
在Java中所有的类都要继承object类,默认也会继承,顶层继承
toString方法
在打印一个对象的时候,默认调用toString方法(toString方法是object类中的)
//toString() ——> 包名+类名+@+内存地址
可以重写toString方法,以达到预期输出效果
IDEA可以提供重写方法,可以看到全部信息
instanceof关键字
-
作用:判断一个对象是不是xx类型的,返回true or false
如:ani instanceof Cat
参数传递问题:内存分析
值传递:把变量的值作为参数进行传递(java使用的是值传递)
public class Test { public static void change(int b ){ b = 20; } public static void main(String[] args) { int a = 10; //局部变量,置于栈中 change(a); System.out.println(a); //结果是10,并未为改变为20 } }
引用传递:直接将变量作为参数进行传递