成员变量与局部变量,栈内存与堆内存,构造方法与实例方法,this关键字,static关键字,面向对象:封装,继承的特性,方法重写;多态,类型转换,final关键字,abstract,interface

成员变量和局部变量:

 在 eat 与 sleep 方法中都是 String 类型的 name, 说明不同的方法,可以有同名的局部变量

          当成员变量与局部变量名称相同时,局部变量更具有优先级

                                          使用 this. 属性,代表成员变量

                成员变量有默认 , 引用数据类型统统默认为 null, int -- 》 0,double --> 0.0  boolean --> false

                局部变量,必须声明,赋值,再使用,否则编译报错,尚未初始化变量

                成员变量的作用域为整个类 , 局部变量只是所定义的方法中或语句块中起作用

                成员变量存在堆内存 , 局部变量存在栈内存

栈内存与堆内存的区别:

栈内存:

存放局部变量

先进先出,自下而上存储

方法执行完毕,自动释放空间

堆内存:

存放new出来的对象

需要垃圾回收器回收

方法区:

存放类的信息(代码),static变量,字符串常量符

构造方法和实例方法的区别:

  (1)构造方法没有返回值,而实例方法必须写返回值,没有返回值,也必须写void

  (2)构造方法的名称必须与类名同名,而实例方法的名称可以自己定义(要求:见名知意)

  (3)构造方法的作用,用于创建对象(实例化对象,)成员方法的作用是描述对象的行为  (对象具备的功能)

  (4)构造方法在创建对象时调用,每调用一次,创建一个对象,而成员方法可以被同一个对象调用N多次

  (5)成员方法必须使用对象调用,构造方法使用new 调用

this关键字:

this:这个,代表当前对象,用于存储当前对象的内存地址

(1)当局部变量与成员变量名称相同时,使用this代表成员变量

(2)使用this可以调用本类中的方法  this.方法名(),this可以省略不写

(3)使用this调用本类中的属性, this.属性名, this可以省略不写

(4)调用本类中的构造方法 this()   ,this(实参列表) ,要求 必须 是构造方法中第一句代码

static关键字

(1)修饰成员变量

(2)修饰成员方法

因为static的属性或方法,在类加载到内存时,一同加载到内存,而这个时候还没有创建对象呢,所以不能使用this,,当前更不能使用this.name    成员变量,也不能使用成员方法

成员方法可以使用成员变量,可以使用静态变量,也可以调用静态方法

(3)可以修饰内部类

(4)可以修饰代码块

  [1]普通代码块:在方法中定义

  [2]构造代码块  :在类中定义的  ,每创建一个对象,都将执行一次,而且优先于构造方法先执行

  [3]静态代码块:在构造代码块前加static,就称为静态代码块

静态代码块在类加载到内存时,一同加载,而且只加载一次,无论创建多少个对象,静态代码块只执行一次

优先于构造代码块先执行

静态代码块--------------->构造代码块------------------------>构造方法

面向对象的三大特征之一,  (封装,继承,多态)

封装

 为什么需要封装?

 因为可以使用不合法的数据进行给属性赋值

如何进行封装?

[1] 属性私有化

[2] 提供公有的取值,赋值方法  , 可以只有取值,也可以只有赋值

[3] 在赋值的方法中进行合法性验证

 this:  

当前对象,  Person p1=new Person ();   this指代就是p1  this与p1所存储的内存相同,都是内存地址

         (1)调用本类的属性   this.属性名

         (2)本类中的非static方法   this.方法名(实参列表);

         (3)调用本类的构造方法  this(),   this(实参列表);  要求必须是构造方法中第一句代码

         (4)当局部变量与成员变量名称相同时,使用this代表的是成员变量

 static:  

          (1)成员变量   -->类变量,静态变量    static String city;   Person 类中的   Person.city

          (2)成员方法  --> 类方法  ,静态方法   public static void show(){}   Person类中   Person.show()

          (3)代码块   -->静态代码块   ,用于给类的静态变量初始化数据

          (4)修饰类
 codeBlock:

           (1)普通代码块

           (2)构造代码块

           (3)静态代码块

封装 :好处,提高程序的安全性

封装的优点

  • 1. 良好的封装能够减少耦合。

  • 2. 类内部的结构可以自由修改。

  • 3. 可以对成员变量进行更精确的控制。

  • 4. 隐藏信息,实现细节。

【1】属性私有化

【2】提供赋值取值方法

【3】在赋值方法中对值进行合法性验证

         实际上就是隐藏细节,提供对方操作的方法         用活中处处用到了封装

 package com.bjsxt.pro;

public class Teacher{   // 讲师类

        //[1] 属性私有化

        private String name ;

        private int teachAge ;

        private String sex ;

        private String course ;

       

        //[2]4 对方法,赋值的方法,取值的方法

        public void setName(String name ){

                this . name = name ;

       }

        public String getName(){

                return name ;

       }

        public void setTeachAge( int teachAge ){

                //[3] 在赋值的方法中,对值进行合法性验证

                if ( teachAge <0){

                        this . teachAge =1;

                       System. out .println( " 教龄赋值有误,已设为默认值 " );

               } else

                        this . teachAge = teachAge ;

       }

        public int getTeachAge(){

                return teachAge ;

       }

        public void setSex(String sex ){

                if (! " 男 " .equals( sex )&&! " 女 " .equals( sex )){

                        this . sex = " 男 " ;

               } else {

                        this . sex = sex ;

               }

       }

        public String getSex(){

       

                return sex ;

       }

        public void setCourse(String course ){

                this . course = course ;

       }

        public String getCourse(){

                return course ;

       }

        //[3] 构造方法

        public Teacher(){

       

       }

        public Teacher(String name , int teachAge ,String sex ,String course ){

                this . name = name ;

                this .setTeachAge( teachAge );   // 调用给教龄赋值的方法

                this .setSex( sex );

                this . course = course ;

       }

}

测试:

package com.bjsxt.pro;

public class TestTeacher{

        public static void main(String [] args){

                //[1] 创建 Teacher 类的对象

               Teacher t= new Teacher( " 张三十 " ,-10, " 女 " , "java" );

               

               System.out.println(t.getName()+ "\t" +t.getTeachAge()+ "\t" +t.getSex()+ "\t" +t.getCourse());

       }

}

继承

好处:提高代码的复用性

继承所使用关键字为extends

写代码: 先写父类,再写子类

父类:

package com.bjsxt.pro;

public class Person {   // 父类

        //[1] 私有属性

        private String name ; // 姓名

        private String sex ; // 性别

        //[2] 公有的取值,赋值方法

        public String getName() {

                return name ;

       }

        public void setName(String name ) {

                this . name = name ;

       }

        public String getSex() {

                return sex ;

       }

        public void setSex(String sex ) {

                this . sex = sex ;

       }

        //[3] 构造方法

        public Person(String name , String sex ) {

                this . name = name ;

                this . sex = sex ;

       }

        public Person() {

                //System.out.println("Person 类的无参构造方法 ");

       }

        public void speak(){

               System. out .println( " 自我介绍 :" );

               System. out .println( " 大家好,我叫 :" + name + " ,性别是 :" + sex );

       }   

}

子类一:

package com.bjsxt.pro;

public class Teacher extends Person { //Teacher 继承自 Person

        // 私有属性

        private int teachAge ;

        private String course ;

        // 公有的取值,赋值方法

        public int getTeachAge() {

                return teachAge ;

       }

        public void setTeachAge( int teachAge ) {

                this . teachAge = teachAge ;

       }

        public String getCourse() {

                return course ;

       }

        public void setCourse(String course ) {

                this . course = course ;

       }

        // 构造方法

        public Teacher(String name , String sex , int teachAge , String course ) {

                super ( name , sex ); // 调用父类的构造方法

                this . teachAge = teachAge ;

                this . course = course ;

       }

        public Teacher() {

                //super();  // 调用父类的无参构造方法, super() 可以省略不写,即使用省略默认调用父类无参构造

                //System.out.println("Teacher 类中的无参构造方法 ");

       }

}

子类二:

package com.bjsxt.pro;

public class Student extends Person {

        // 私有属性

        private String stuNo ;

        private int age ;

        public String getStuNo() {

                return stuNo ;

       }

        public void setStuNo(String stuNo ) {

                this . stuNo = stuNo ;

       }

        public int getAge() {

                return age ;

       }

        public void setAge( int age ) {

                this . age = age ;

       }

        // 构造方法

        public Student(String name , String sex , String stuNo , int age ) {

                super ( name , sex );

                this . stuNo = stuNo ;

                this . age = age ;

       }

        public Student() {

                super ();

       }

}

测试:

package com.bjsxt.pro;

public class Test {

        public static void main(String[] args ) {

               Teacher t = new Teacher( "mary" , " 女 " ,10, "java" );

                t .speak();   // 这个方法是 Person 类中的方法

               

               Student stu = new Student( "jack" , " 男 " , "sxt1001" , 20);

                stu .speak();

       }

}

继承的特性:

【1】单根性  : 一个子类只能直接继承一个父类

【2】传递性 :

public class A {

        public int money =100000000;

}

public class B extends A {

}

public class D extends B {

        public void show(){

               System. out .println( super . money );

       }

}

public class TestD {

        public static void main(String[] args ) {

                D d = new D();

                d .show();

       }

}

一个类如果没有显示写extends,那么默认继承Object类  ,Object是所有的类的直接或间接父类

public class Person {  

}

相当于

public class Person   extends Object{  

}

继承

:先写父类,再写子类,  子类使用extends继承父类

               (1)继承非private的属性

               (2)继承非private的方法

               (3)构造方法,子类可以调用,但不能继承

当父类提供的方法不能满足子类的需求,子类需要重写这个方法

重写:

[1]在子类

[2]方法的名称必须与父类的方法名称相同

[3]方法的参数必须与父类中定义的方法的参数个数,顺序,类型完全相同

[4]子类重写方法的返回值类型与父类中的方法的返回类型相同,或者是父类方法返回值的子类

package com.bjsxt.pro;

public class Father {     

        public Father show(){
                //Father f=new Father();
                //return f;
                return new Father();
       }
}

子类重写之后,与父类方法的返回值类型相同

package com.bjsxt.pro;

public class Son extends Father {

        @Override

        public Father show() {

                // TODO Auto-generated method stub

                return super .show();
       }
}

或者,子类重写之后,是父类方法返回值类型的子类

package com.bjsxt.pro;

public class Son extends Father {

        @Override

        public Son show() {

                // TODO Auto-generated method stub

                return new Son();

       }

}

[5]访问权限大于等于父类方法的访问权限

如果父类方法的访问权限为protected,那么子类重写时,可以为protected或public

类的成员 (属性和方法)  

  private: 只能本类中访问

  default: 只能本包中访问

  protected:只能子类访问

  public:公共的,访问权限最大的

子类不能重写父类的哪些方法?

(1)子类不能重写父类的private方法

(2)子类不能重写父类的构造方法

(3)子类不能重写父类的static方法

一个类如果没有使extends继承任何类,默认继承Object,Object类是所有的类的直接或间接父类

super关键字

    this:代表当前对象   ,可以调用本类的属性,本类的方法,本类的构造方法(要求必须是第一句代码)

    super:指向直接父类,只是一个关键字而已,这个关键字只能出现在子类中

             (1)调用父类的非private属性

              (2)调用父类的非 private方法

              (3)调用父类的构造方法 super()   ,super(实参列表)

 只要创建子类对象就会调用父类的构造方法,如果没有指定,默认调无参

父类:

package com.bjsxt.super1;

public class Person {

        private String name = " 张三 " ;

        int age ;

        public String getName() {

                return name ;

       }

        public void setName(String name ) {

                this . name = name ;

       }

        public Person(String name , int age ) {

                super ();   // 调用的是 Object 类的无参构造方法

                this . name = name ;

                this . age = age ;

       }

        public Person() {

                super ();

               System. out .println( "Person" );
       }
}

子类:

package com.bjsxt.super1;

public class Employee extends Person { // 工人

        private String deptment = "java 学院 " ; // 部门

       

        public String getDeptment() {

                return deptment ;

       }

        public void setDeptment(String deptment ) {

                this . deptment = deptment ;

       }

   

        public void show(){

               System. out .println( super.getName() + "\t" + super .age );

               

       }

        public Employee(String name , int age , String deptment ) {

                super(name, age);   // 调用父类的带参构造方法

                // 默认调用无参

                this . deptment = deptment ;

       }
        public Employee() {

                super();  // 可以省略不写

       }
}

测试:

package com.bjsxt.super1;

public class Test {

        public static void main(String[] args ) {

               Employee e = new Employee( " 李四 " , 20, " 财务部 " );

               System. out .println( e );
       }
}

封装与继承的区别:

封装是提高代码的安全性(属性私有化,提供共有的取值赋值方法,在赋值方法中对值进行合法性验证)

继承提高代码的复用性(子类继承父类,重写父类中的非private属性,非private方法,调用构造方法)

面向对象的三大特征

(1)封装  :提高程序的安全性

(2)继承 :提高代码的复用性  

       extends ,   --》Object   (toString(),equals(Object obj))

       父类 :属性(每个子类都会具有的属性)

                成员方法(每个子类都具有的行为)

                构造方法 (可以提供给子类调用)

       子类:属性(子类特有的属性)

                成员方法(每个子类特有的行为)

                构造方法

   方法重写: 如果父类提供方法,不能满足子类的需求,子类就可以重写父类中的方法

            (1)方法的名称,参数的类型,个数,顺序必须与父类中的方法完全相同

            (2)返回值可以与父类的返回值相同,也可以是父类方法返回值的子类

            (3)子类在重写时,访问权限与父类相同,或者访问权限比父类

  访问权限修饰符:

    (1)修饰类时:两种

          default(package),   public

    (2)修饰成员时:4种

           private :本类

           default:本包

           protected:子类

           public:都可以访问

   

super关键字:

     它只能出现在子类中,用于访问父类的成员  (非private的成员)

      调用父类的构造方法 super()     super(实参列表)

多态

 多态有前提条件是继承,没有继承无从谈多态

 使用多态的步骤:

  (1)编写父类

  (2)编写子类,子类重写父类中的方法

  (3)使用父类指向子类对象

多态有两种表现形式

  (1)父类作方法的形式参数

         Object类中的equals( Object obj )  

  (2)父类作方法的返回值

类型转换

(1)向上类型转换/自动类型转换  :子转父  --》只能调用父类中的方法(继承的方法或者重写的方法)

(2)向下类型转换/强制类型转换  :父转子  --》 可以调用父类中的方法及子类中特有的方法

  向下转换容易产生异常 ClassCastException类型转换异常,  要求向下转换必须转换成真实的子类对象

 Car tc = new TaxiCar( " 北京现代 " , " 京 B23234" , " 景顺 " );

                  Car mc = new MyCar( " 奥迪 A8" , " 京 P88434" , " 武大郎 " );

               

               

               

                c.start();

               c.stop();

               System. out .println( "\n---------------------------------\n" );

                mc.start();

               mc.stop();
public class TestEquals {

        public static void main(String[] args ) {

                // 父类 new 子类对象   -- 》进行了向上类型转换,转成了 Object 类型

                Object c = new Car ();   //

                //c 只能调用 Object 类中的方法

               

                //c.start(); 9 行与 10 行报错,因为这两个方法是子类 Car 特有的方法

                //c.stop();   如果想调用这两个方法,必须向下类型转换

                MyCar my= (MyCar)c;   //ClassCastException 类型转换异常,向下转型时,必须转换成真实的子类对象

                my .start();

                my .stop();

               

                //System.out.println(" 男 ".equals(c));

       }

}

在向下转型时,通常需要进行真实子类类型的判断, instanceof   进行判断判断,返回值为true或false

小结:

   (1)多态的操作步骤:  父类,子类,子类重写方法,  父类创建子类对象

    (2)父类作方法的返回值,父类作方法的形式参数

    (3)类型转换  

final关键字

   (1) 修饰变量 (成员变量,局部变量)

              public   static final   double PI =3.1415926;   // 静态常量

             final修饰局部变量时,不允许使用 public static

   (2) 方法    不能被子类重写,但是子类可以调用

不能从Object类中重写这个final方法

(3) 类    (太监类) :不能有子类的

              TestFinal类不能是终级类Math类的子类,因为API 中Math类的定义为final

           public final class Math

final可以与static一起使用

final不能与abstract一起使用

abstract抽象

 (1)修饰类  :抽象类

  public abstract class Father {

    }

抽象类可不可以有构造方法? 可以

  抽象类中的构造方法的作用? 提供给子类调用

父类:

 public abstract class Father {

        private String name ;

        public Father(){

               

       }

        public Father(String name ){

                this . name = name ;

       }

}

子类:

public class Son extends Father {

        public Son() {

                super();

                // TODO Auto-generated constructor stub

       }

        public Son(String name ) {

                super(name);             

       }  

}

 abstract类中可以有如下方法  (final修饰的方法,成员方法,static方法 ,构造方法)

public abstract   class Father {

        public final void show(){

               

       }

        // 成员方法

        public void fun(){

               

       }

        //static 方法

        public   static void method(){

               

       }

}

 (2)修饰方法: 抽象方法    :含 有抽象方法的类必须是抽象类

public abstract class Animal {

        public abstract void shout();

}

 如果子类不实现父类的抽象方法,那么子类也必须是抽象类

public abstract class Cat extends Animal {

}

重写与实现在的关系:

子类可以重写父类中的方法,也可以不重写   (绿色实心三角)

子类必须实现父类中的抽象方法,如果不实现,必须也是抽象类   (白色三角)

interface接口

  如果一个类中所有的方法都是抽象方法,那么可以把这个类定义为interface

接口的初步了解

public interface A {

        public abstract void show();

        public abstract String fun();

        public abstract int [] method();

        public abstract Car [] perList();

}

可以改写为

public interface A {

        void show();

        String fun();

        int [] method();

        Car [] perList();

}

接口中所有的方法均为公共的抽象方法,所以可以将public abstract省略不写

接口中不允许定义构造方法

接口中只能有公共的静态常量 public static final

public static final String name = " 张三 " ;

那么public static final可以省略不写  

public interface A {

       String name = " 张三 " ;
}

接口中的方法均为public abstract方法,这些方法需要类去实现,所以接口与类的关系为实现关系,使用关键字

implements

public class AImple implements A {

        @Override

        public void show() {

                // TODO Auto-generated method stub

               

       }

}

如果一个类即存在继承关系又存在实现关系   要求extends在前,implements后

一个类只能继承一个父类但可以实现N多接口

 智能手机 is a 手机 has a 拍照的功能, has a 上网的功能, has  a 播放视频的功能

 防盗门 is a 门     has a 锁的功能

 防盗 门  is a 锁  --》 不成立

一个类只能直接继承一个父类,但可以实现N多接口

接口的特征:

【1】多继承

public interface InterA {

        public void show();

}

public interface InterB {

        public void fun();

}

public interface InterC extends InterA, InterB {

}

【2】传递性

多态的操作步骤:

【1】编写父类 / 接口

【2】编写子类,重写父类中的方法  / 实现接口中的方法

【3】父类new子类对象 (父类引用指向子类对象)  / 接品new 实现类

在API中java.util.Comparator接口,用于比较两个对象的大小,实现排序用

接口的应用

package com.bjsxt.inter3;

import java.util.Comparator;

public class ComLength implements Comparator { //Comparator 接口具备了比较大小的能力

        @Override

        public int compare(Object o1 , Object o2 ) {   // 父类 Object 作方法的形式参数

                // 向下类型转换

               String str1 =(String) o1 ;

               String str2 =(String) o2 ;

                /*if(str1.length()>str2.length()){

                       return 1;

               }else if(str1.length()<str2.length()){

                       return -1;

               }

               return 0;*/

                return str1 .length()- str2 .length();
       } 
}

测试:

package com.bjsxt.inter3;

import java.util.Arrays;

import java.util.Comparator;

public class Test {

        public static void main(String[] args ) {

               String [] str ={ "grape" , "banana" , "apple" , "pink" };

               Arrays. sort ( str );

               System. out .println(Arrays. toString ( str ));

               

               /** 不希望按字母升序排,我想接照单词的字每长度排序 */

                //(1) 自己写比较规则

                //(2) 定义一个类实现 Comparator 的接口

                //(3) 实现接口中的方法  , 在方法写比较规则

               

                //(4) 使用接口 new 实现类

               Comparator com=new ComLength ();

                //(5) 调用排序的 sort 方法

                Arrays. sort (str, com);

               System. out .println(Arrays. toString ( str ));

               

       }

}

猜你喜欢

转载自blog.csdn.net/wyqwilliam/article/details/81835693