本文共 7259 字,大约阅读时间需要 24 分钟。
封装 隐藏实现细节,对外只提供公共访问的访问方式; 在java中封装的体现: 1)方法: 对方法的实现不用考虑其怎么实现的,只要告知了我们方法的名称 参数类型 作用和返回值类型,这个方法我们就能使用; 2)对象: 对象就封装了数据和功能,只要拿到这个对象,就能使用这个对象的数据个和功能了; 3)私有化类的成员属性,对外给属性提供公共的getXxx/setXxx方法去间接的给属性 取值和赋值; 怎么取值怎么赋值不是我们关心的,我们只关系get方法可以取到值,set方法可以赋值 就可以了;
对于类的成员(属性、方法)的访问控制,四种修饰符都可以使用每种权限修饰的成员的使用范围见图
类:默认,public,final,abstract我们自己定义:public居多成员变量:四种权限修饰符均可,final,static我们自己定义:private居多构造方法:四种权限修饰符均可,其他不可我们自己定义:public 居多 成员方法:四种权限修饰符均可,fianl,static,abstract我们自己定义:public居多
代码如下:
public class Demo4 { public static void main(String[] args){ /* Employee emp1 = new Employee(); emp1.name = "jack"; emp1.age = -10; //jack -10 程序的执行没有问题,而是程序不符合生活逻辑问题; emp1.show(); System.out.println("======================="); */ /* //判断处理 int age = -10; if(age>=0 && age<=120){//合法年龄 emp1.age = age; }else{//非法年龄 emp1.age = 0; } emp1.show(); System.out.println("----------------------"); Employee emp2 = new Employee(); emp2.name = "rose"; //判断处理 age = -20; if(age>=0 && age<=120){ emp2.age = age; }else{ emp2.age = 0; } emp2.show(); //代码复用性问题 System.out.println("-----------------------"); */ Employee emp3 = new Employee(); emp3.name = "smith"; emp3.setAge(-20); emp3.show(); //emp3.age = -20; //emp3.show(); //如果使用员工对象的封装方法setAge()去给员工的age属性赋值,就能对员工年龄进行逻辑 //判断再赋值的效果;但是仍然可以使用 对象.属性 的方式给员工的age属性赋值呀,那么问题 //又回到一开始的问题了; //问题是:只能去使用员工对象的setAge()方法进行逻辑判断并给age属性赋值,而不让使用 //对象.属性 的方式去给员工对象的age属性赋值; emp3.setAge(22); emp3.show(); System.out.println("-----------------------------"); Student s = new Student(); s.setSno(101); s.setName("jack"); s.setAge(21); s.show(); System.out.println(s.getSno()+" "+s.getName()+" "+s.getAge()); }}//员工描述类class Employee{ //成员属性 String name; private int age; //成员方法 public void show(){ System.out.println(name+" "+age); } /* 对年龄的判断进行了一个方法的封装,就能提高代码复用性了,同时 将这个方法给定成了员工的功能方法,即就是只要是个员工(对象)都 具有该功能; */ public void setAge(int a){ if(a>=0 && a<=120){ age = a; }else{ age = 0; } }}class Student{ //成员属性 private int sno; private String name; private int age; //get/set public void setSno(int no){ sno = no; } public int getSno(){ return sno; } public void setName(String n){ name = n; } public String getName(){ return name; } public void setAge(int a){ age = a; } public int getAge(){ return age; } //成员方法 public void show(){ System.out.println(sno+" "+name+" "+age); System.out.println(getSno()+" "+getName()+" "+getAge()); }}
继承 当多个类有共同的属性和方法时,可以抽取出一个父类 继承的主要作用就是为了实现代码的复用,简化编写 注意:并不是所有的有共同属性和方法的类都可以使用继承,使用继承必须要满足一个is a 的关系 关键字: extends 被继承的类叫父类 继承的类叫子类 1.子类继承父类的,可以将父类中所有的非私有内容继承过来 2.子类中还可以有自己的特有属性和方法 3.子类还可以重写父类的中的方法 什么时候子类需要重写父类中的方法 父类的方法不能满足子类的需求的时候 4.构造方法不能被继承 5.java中,类与类之间是单继承 6.java中所有的类都直接或间接的继承object类 如果指明了父类,间接的继承object类 如果没有指明父类,默认直接的继承object类
this:当前对象的使用 1.使用this区分成员变量和局部变量 2.在方法中使用this调用本类的其他方法 3.在构造方法中调用本类中调用本类的其他构造方法 super:父类对象引用 1.super可以调用父类的成员变量和方法 2.super在构造方法中调用父类的构造方法 在一个构造方法中,super()和this()不能共存 构造方法的特殊性: 当创建子类对象调用子类的对象的构造方法,会默认调用父类的无参构造方法 我们无法控制构造方法的执行顺序,总是先执行辈分大的类的构造方法 Super和this的区别 1. this在方法中调用本类的其他方法,super在方法中调用父类的方法 2. 在构造方法中,this可以在构造方法中去调用本类的其他构造方法,super在构造方法中调用父类的构造方法 3. This和super构造方法中使用的时候都必须放在构造方法代码的第一行
final可以修饰类、变量、方法 final修饰的类叫最终类,最终类不能被继承 String类就是最终类 不能被继承 final修饰变量,变为常量,只能被赋值一次 赋值要在创建对象之前赋值 赋值的时机: 1.声明常量的时候直接赋值 2.构造方法内赋值 3.可以在构造代码块中赋值 4.如果是静态常量还可以可以在静态代码块中赋值 final修饰的方法不能被重写 final修饰形参,形参值不能被改变 形参可以被使用,但是不能改变形参的值 instanceof 比较关键字 判断一个对象是不是一个类的对象
代码如下:
animal类public class Animal { private String name; private int age; private String sex; public Animal() { } public Animal(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public void eat(){ System.out.println(".....吃草"); } public void sleep(){ System.out.println("....睡"); } }
cat类
//Cat继承Animalpublic class Cat extends Animal { public void climb(){ System.out.println("....猫爬树"); } //重写父类的eat方法 public void eat(){ System.out.println("....猫吃鱼"); }}
dog类
//Dog继承Animalpublic class Dog extends Animal { public void look(){ System.out.println("...狗看门"); } //重写父类的eat方法 public void eat(){ System.out.println("....狗吃骨头"); }}
测试类
public class Test { public static void main(String[] args) { //创建一个Cat的对象 /*Cat c=new Cat(); c.eat(); c.sleep(); c.setName("花花"); String name=c.getName(); System.out.println(name); c.climb(); //创建一个Dog对象 Dog d=new Dog(); d.sleep(); d.look();*/ //instanceof 判断一个对象是不是一个类的对象 Cat c=new Cat(); Dog d=new Dog(); System.out.println(c instanceof Cat);//判断对象c是不是Cat类的对象 //System.out.println(c instanceof Dog);//编译报错 System.out.println(c instanceof Animal); Animal a=new Animal(); System.out.println(a instanceof Cat);//false }}
多态: 一个事物(对象)在不同的情况下可以有不同的形态实现多态的前提: 1.要有继承关系 2.要有子类去重写父类的方法 如果没有也可以,但是没有方法重写的多态是没有意义的 3.要有父类引用指向子类对象 多态的特点: 父类指向子类的对象 1.通过父类引用调用子类对象重写后的方法时,调用的是子类 重写后的方法 2.父类引用不能调用子类对象特有的方法 动态绑定 Animal a = new Cat(); 在编译期,对于一个引用并不能确定它的具体类型,在运行期才能具体确定 它的具体类型 3.如果非要调用子类特有的方法 向上转型 将子类类型转换为父类类型----自动转换 子----父 向下转型 将父类类型转换为子类类型-----强制转换 目标类型 名 = (目标类型)引用; 编译看左边,执行看右边 只有普通方法具有多态性final、static、private方法不具有多态性成员变量,不具有多态性表面上的内容它不具有多态性,实际的行为才具有多态性多态的作用:1.提高了程序的维护性(由继承保证)2.提高了程序的扩展性(由多态保证)增强for循环------for-each循环增强for循环主要是为了 为了遍历数组或者集合中的元素for(遍历的单个元素的数据类型 存放单个元素的变量:要遍历的集合或者是数组){ 循环体}多态的缺点: 父类的引用不能调用子类的特有的方法 抽象: abstract 抽象类 用abstract修饰的类 叫抽象类 如果一个类,没有具体的对象,可以将一个类定义为抽象类抽象类的特点: 1.抽象类不能实例化 2.重选另类存在的惟一的意义就是被继承 3.有抽象方法的类一定是抽象类,但是抽象类不一定有抽象方法 4.抽象类中的可以有抽象方法,也可以有非抽象方法抽象方法:用abstract修饰的方法,方法只有方法的声明,没有方法的具体实现抽象方法相当于一个规则,一个标准指明了只要是这个类型,就要有这个功能抽象类的成员特点: 1.抽象类可以有成员变量 2.抽象类可以有构造方法,但是不能被实例化 3.抽象类可有抽象方法,也可以有非抽象的方法 abstract不能和以下的关键字共存private冲突,final冲突,static无意义接口: 接口是比抽象类更抽象的东西 1.接口中所有的方法都是抽象方法 接口中定义的方法默认的访问修饰符 public abstract 2.接口没有构造方法,也不能被实例化 3.接口存在的意义就是被实现implements 4.如果一个类要实现一个接口,就需要实现接口中的所有的方法 5.抽象类中可以有抽象方法 6.抽象类可以有普通的成员变量 接口作用: 接口就是一个规则,规范 一个类实现了接口,就代表这个类遵守接口的规范 有了抽象类为什么还有接口 将抽象类中的所有方法定义成抽象方法和接口有什么区别 Java中的类的继承具有很大的局限性,java中的继承只能是单继承 一个子类只能有一个直接的父类 类实现接口是可以多实现,也就是说一个类可以实现多个接口 类和类的关系:单继承 类和接口的关系;多实现 接口和接口的关系: 多继承,一个接口可以继承多个接口
代码如下:
利用上面的animal,cat,dog类,在写一个测试类public class Test { public static void main(String[] args) { /*Cat c1=new Cat(); Dog d1=new Dog();*/ //父类引用指向子类对象 Animal a1=new Cat(); a1.eat();//调用的是子类重写后的方法 a1.sleep(); //父类引用不能调用子类特有的方法 //a1.climb(); //如果非要调用子类特有的方法,使用向下转型强制的将父类类型转换为子类类型 Cat c=(Cat)a1; c.climb(); a1.fun(); System.out.println(a1.n);//10 /*Animal a2=new Animal(); Cat c2=(Cat)a2;*/ /*Animal a3=new Dog(); Cat c3=(Cat)a3;*/ /*Cat.fun(); Animal.fun();*/ /*Animal a2=new Dog(); a2.eat(); Animal a3=new Animal(); a3.eat();*/ }}
转载地址:http://mxewi.baihongyu.com/