面向对象
文章目录
面向对象1.修饰符1.1private**1.2没有private****1.3有private**2.继承2.1概念2.2父类子类3.构造方法3.1构造方法的作用3.2无参构造3.3有参构造4.访问修饰符5.程序的初始化流程6.方法重载和方法重写6.1重载6.2重写7.抽象类定义8.关键字final9.多态:歧义9.1没用多态9.2用多态了9.3多态的几种实现方式9.4多态时父类和子类的转换9.5接口10.Java值传递问题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-159770146)(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 如果不是返回falsePenguin penguin = (Penguin)pet;penguin.playSwimming}}
9.5接口
1.方法都是public abstract默认
2.属性都是 static final默认
接口比抽象类 更进一步抽象
类:单继承
接口:接口之间可以相互继承、多继承
接口也可以实现多态接口 引用 = 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}}