面向对象
文章目录
1.修饰符
1.1private
一般建议对属性/方法,加访问修饰符
priavate:私有的:只有当前类能够访问(同一个类),其他类不能直接访问,如果要访问,需要借助于访问器。
setter,getter
set :设置
get :取
1.2没有private
信息不安全,谁都可以访问
package hello.world;
public class Person {
String name ;
int age ;
public void showInfo(){
System.out.println(name +"----" +age);
}
}
package hello.world;
public class TestPerson {
public static void main(String[] args) {
Person per = new Person();
per.name = "zs" ;
per.age = 1231 ;//数据不安全
per.showInfo();//zs----1231
}
}
1.3有private
package hello.world;
public class Person {
private String name;
private int age;
//set:增删改,赋值
//get:查
public void setName(String n) {
name = n;
}
public void setAge(int a) {
//安全
if (a >= 0 && a < 120) {
age = a;
} else {
age = -1; //标识-1代表错误
System.out.println("年龄有误");
}
}
public String getName() {
return name;
}
public int getAge() {
if (age >= 0 && age < 120) {
return age;
} else {
System.out.println("值有误");
return -2; //标识-1代表错误
}
}
}
package hello.world;
public class TestPerson {
public static void main(String[] args) {
Person per = new Person();
per.setName("zs");
per.setAge(140);
System.out.println(per.getAge() + "----" + per.getName());
}
}
注意
public void setName(String name) {
this.name = name;//this.name代表了当前类的属性
}
2.继承
2.1概念
继承:减少冗余(重复)
如果很多类的属性、方法 重复出现,重复---->父类,继承
面试题
什么情况下严格继承
is a 是一个
子类 是一个 父类 || 狗是一个宠物
注意:如果一个方法,方法名相同,但方法体不同,也不能提取到父类
只有完全相同的属性、方法,能提取到父类
子类继承父类:private、构造方法是不能被继承的,但是 子类可以显示的调用父类的构造
super
2.2父类子类
如果子类中调用方法a(),
首先在本子类中找a()方法如果没则继承父类的方法a() && this
关键字默认找本子类方法(和不加关键字等价)
但是如果方法a()前有spuer
关键字那么系统跨过子类直接取父类中寻找a()
this
当前类中寻找 调用本类构造方法 (第一行)this(“s”);||this();
super
父类中寻找 调用父类构造方法(第一行) super(“s”)||super() ;
3.构造方法
3.1构造方法的作用
1.实例化(产生对象) Dog dog = new Dog();
2.有参构造:一次给多个属性赋值
结构
无参构造方法:
public 类名(){
}
注意事项
1.构造方法不能通过方法名直接调构造方法:Dog dog = new Dog();
2.普通方法:Dog(“旺旺”);
3.多个构造方法之间不能死循环
4.构造方法直接可以相互调用,this(); (必须写第一行)
4.例子
private String strain;
private String other ;
public Dog(String strain, String other){
this.strain ;
this.other ;
}
public Dog(String strain){
this.strain ;
}
public Dog(){
this("a");//通过参数的个数来确定某个构造方法
}
3.2无参构造
如果类中没有任何构造方法,则系统自动提供一个无参构造
如果类中存在任何构造方法,则系统不在提供无参构造
一般建议:如果给类中编写构造方法,则手动编写一个无参构造防止报错
mian里写
Dog dog = new Dog();
//真正的无返回值
Public class Dge {
public Dog(){
System.out.println("无参构造");
}
}
3.3有参构造
含参构造方法的作用:一次性给多个属性赋值
//多个属性赋值
private String strain;
private String other ;
public Dog(String strain, String other){
this.strain ;
this.other ;
}
4.访问修饰符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YeQkHdSO-1597200470146)(C:\Users\Wides\Desktop\b&bo=dAP8AAAAAAADB6k!&rf=viewer_4)]
5.程序的初始化流程
在子类中创建新对象时,默认子类中的无参构造方法super();方***调用父类中的无参构造方法
在创建对象时如果有static静态代码块,只执行一次(初始化)
在创建对象时如果有普同代码块{}那么在每次无参构造之前都会调用普通代码块
Son son = new Son(); 调用流程
1.父类static…
2.子类static…
3.父类普通代码块…
4.父类无参…
5.子类普通代码块…
6.子类无参…
6.方法重载和方法重写
6.1重载
1.方法名相同
2.参数列表不同(类型、类型、顺序)
注意:1.与返回值无关
3.和参数名无关
6.2重写
父类有一个方法,子类重新写了一遍
1.方法名相同
2.参数列表相同
面试题:
构造方法是否能被重写?
否;因为构造方法不能被继承,而方法重写的要求是父子关系
7.抽象类
1.多个子类中用用相同的方法:将其提取到父类中,再继承即可
2.多个子类的方法 各不相同 :各自处理,不要往父类中放
3.多个子类中的方法 方法标签相同 ;但是方法体不同(两个类中的print();方法) :抽象方法
定义
抽象方法:只写方法标签 ,不写方法体;并且用abstract修饰
抽象方法必须包含在抽象类中,抽象类中不一定有抽象方法
抽象类不能实例化(抽象类中可能存在抽象方法,而抽象方法没有方法体,不能实现)
8.关键字final
注意:final最终的
- final修饰的类:不能被继承
- flinal修饰的方法:不能被重写**(override)**
- final修饰的变量:不能比被修改
9.多态:歧义
一个词语,必须根据上下文才有实际的含义
eg. 打:打水、打架、打篮球
结构
父类 引用对象名字 = new 子类();
父类引用指向子类对象
引用在栈空间中,子类对象在堆空间中
9.1没用多态
抽象类Pet宠物
package Pet;
public abstract class Pet {
public abstract void eat();
}
实现类:吃鱼
package Pet;
public class Penguin extends Pet {
public void eat(){
System.out.println("吃鱼");
}
}
实现类:吃狗粮
package Pet;
public class Dog extends Pet {
public void eat(){
System.out.println("吃狗粮");
}
}
主人类喂养宠物
package Pet;
public class Master {
public void feedDog(Dog dog){
System.out.println("吃狗粮");
dog.eat();
}
public void feedPenguin(Penguin penguin){
System.out.println("喂鱼");
penguin.eat();
}
}
测试调用
package Pet;
public class TestMaster {
public static void main(String[] args) {
Master master = new Master();
Dog dog = new Dog();
Penguin penguin = new Penguin();
master.feedDog(dog);
master.feedPenguin(penguin);
}
}
9.2用多态了
抽象类Pet宠物
package Pet;
public abstract class Pet {
public abstract void eat();
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
实现类:吃鱼
package Pet;
public class Penguin extends Pet {
public void eat(){
System.out.println("吃鱼");
}
}
实现类:吃狗粮
package Pet;
public class Dog extends Pet {
public void eat(){
System.out.println("吃狗粮");
}
}
主人创喂方法通过传进来的宠物来喂养该宠物
package Pet;
public class Master {
//这就是多态
//第一次
//Pet pet = new Dog();
//第二次
//Pet pet = new Penguin();
public void feed(Pet pet){
System.out.println("喂"+pet.getName());
pet.eat();
}
}
测试,给了宠物名字
package Pet;
public class TestMaster {
public static void main(String[] args) {
Master master = new Master();
Pet dog = new Dog();
dog.setName("狗");
Pet penguin = new Penguin();
penguin.setName("企鹅");
master.feed(dog);
master.feed(penguin);
}
}
9.3多态的几种实现方式
1.方法的重写
2.方法的继承
3.使用父类作为方法的形参
4.使用父类作为方法的返回值
package Pet;
public class Master {
//这就是多态
//第一次
//Pet pet = new Dog();
//第二次
//Pet pet = new Penguin();
public void feed(Pet pet){
System.out.println("喂"+pet.getName());
pet.eat();
}
public static Pet getPet(int typeId){
Pet pet = null ;
if(typeId==1){
pet = new Cat();
}esle if(typeId==2){
pet = new Dog();
}else{
pet = new Penguin();
}
return pet ;
}
}
package Pet;
public class TestMaster {
public static void main(String[] args) {
Master master = new Master();
Pet dog = Master.getPet(2);
dog.setName("狗");
Pet penguin = Master.getPet(3);
penguin.setName("企鹅");
master.feed(dog);
master.feed(penguin);
}
}
9.4多态时父类和子类的转换
-
从小到大自动转换
Pet pet = new Dog();
-
从大到小强制转换
Dog dog = (Dog)(new Pet());
public void play(Pet pet){
if(pet instanceof Dog){
Dog dog = (Dog)pet ;
dog.plagCaching();
}else if(pet instanceof Penguin){
//对象 instanceof 类型
//如果是真返回true 如果不是返回false
Penguin penguin = (Penguin)pet;
penguin.playSwimming
}
}
9.5接口
1.方法都是public abstract默认
2.属性都是 static final默认
类别 | 代表 | 方法 |
---|---|---|
普通类class类 | 底层员工 | 具体实现方法 |
抽象类:abstract class 类 | 中层领导 | 可以有抽象方法可以有实现方法 |
接口:interface | 高层老板 | 全部是抽象方法 |
接口比抽象类 更进一步抽象
类 | 意义 | 实例 | 实现 | ||
---|---|---|---|---|---|
继承 | is a | 狗是一个宠物 | 类 抽象类 | 不能new实例化 | 父类eat()–(extends)>子类 |
接口 | has a | 门有锁的功能 | 类 接口 | 不能new实例化/ | 接口eat()–(implements)>实现类 |
类:单继承
接口:接口之间可以相互继承、多继承
接口也可以实现多态 接口 引用 = new 实现类();
接口中不能有构造方法
作业1
防盗门:
开锁、关锁
开门、关门
先继承后实现,如果继承只能继承一个但是可以实现多接口
关系 | 重写 | |
---|---|---|
防盗门是门(开门关门) | 继承关系 | 子类必须重写父类中的额所有抽象方法 |
防盗门有锁的功能(开锁、关锁门) | 接口关系 | 实现类必须实现接口中的所有抽象方法 |
作业2
打印机:
墨盒:彩色、黑白
纸张:A4、A5
实现类:真正制作打印机的厂商
10.Java值传递问题
基本参数类型在方法传值过程中调用方法中的基本参数类型值改变,原值不改变
引用类型会改变
public class Main{
public static void aMethod(int num1,Per per1){
num1 = 11;
per1.age = 11;
}
public static void main(String [] args){
int num = 10 ;
Person per = new Person();
per.age = 10 ;
aMethod(num,per);
System.out.print(num+","+per.age);
//10,11
}
}
习题
public class String(){
public static void main(String[] args){
String str = "A";
StringBuffer sbB = new StringBuffer("B");
StringBuffer sbC = new StringBuffer("C");
change(str,sbB,sbC);
System.out.println(str+","+sbB+","+sbC);
}
//String :final 类型的,当传入chang()方法时,mian中的str和change中的str1指向的是同一个"A"
//但是当Str1的值发生改变时,因为str1是final类型的,因此str1是脱离原先的"A"而指向新的值"A1"
//sbB是StringBuffer:是普通的引用类型,如果有两个引用(sbB,sbB1)则该两个引用始终指向同一个值"B"
//任何一个引用对"B"进行修改,都会改变它引用所指向的值
//sbC虽然也是StringBuffer,但是 new StringBuffer("c1");了一下,所以sbC产生了新的引用(与原来的引用断开了)
public static void change(String str1, StringBuffer sbB1,StringBuffer sbC1){
str1 = str+"1";
sbB1 = append("1");
sbC1 = new StringBuffer("c1");
//A B1 C
}
}