week4学习总结

Firstday             

面向对象的多态性

学习目标:
1. Object类的toString()与equals(Object  obj)方法
2. 面向对象的多态性
3. 抽象类与接口

一:Object类
Object类是所有Java类的根基类(“祖先类”)
如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类
eg:
public class Person{
...
}
等价于:
public class Person extends Object{
...
}
1.1.toString 方法
Object类中定义有public  String toString()方法,其返回值是String类型,描述当前对象的有关信息。
   如果直接打印某对象的引用,则默认会调用这个对象的toString()方法,默认打印的内容中包含这个引用所指向的内存地址。
可以根据需要在用户自定义类中重写toString()方法。
eg:
public String toString() {
return "Student [name=" + name + ", age=" + age + ", score=" + score
+ "]";
}
}
1.2.equals()方法
Object类中定义有public boolean equals(Object obj) 方法,提供定义对象是否“相等”的逻辑。
Object的equals方法定义为:x.equals(y),当x和y指向同一个地址时返回true,否则返回false。
String类中已经重写了equals(Object  obj)方法,重写后的方法比较的是两个字符串的”内容”是否一样(注意:==比较对象的引用)。
可以根据需要在用户自定义类型中重写equals方法。
eg:package object;


public class EqualsDemo {


public static void main(String[] args) {
Student stu1=new Student("张三",20,83.5);
Student stu2=new Student("张三",20,83.5);      
System.out.println("stu1与stu2相等吗?"+stu1.equals(stu2));
 //new相当于开辟了俩新地址,所以这里输出结果为false
}
}
eg2:
package string.trap;


public class StringEquals {


public static void main(String[] args) {
        String str1="hello";
        String str2="hello";
        System.out.println(str1==str2);
        System.out.println(str1.equals(str2));
        System.out.println("*********************************");
        String str3=new String("hello");
        System.out.println(str1==str3);
        System.out.println(str1.equals(str3));
}
}
输出结果:true          true           *********************************        false       true
二:多态性
多态性的体现:
1.从方法的角度来看:
方法的重载与重写
重载(overloading):根据传入的参数不同,完成的功能也不同
重写(override):子类根据需求重写父类中的方法。
2.从对象的角度来看:
对象的多态性主要分为两种:
向上转型: 子类对象->父类对象  (程序会自动完成)
    格式:
父类 父类对象=子类实例
向上转型后,因为操作的是父类对象,所以无法找到在子类中定义的新方法;但如果子类重写了父类的某个方法,则调用的是重写后的方法。
向下转型:父类对象->子类对象 (必须明确的指明要转型的子类类型)格式:
子类 子类对象=(子类)父类实例
注意:向下转型前先要向上转型。

(1)向上转型:
eg:
父类:
package duotai.upper;

public class Person {
private String name;
private int age;


public Person() {
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void say() {
System.out.println("我是父类方法say(),姓名:" + this.name + ";年龄:" + this.age);
}
public void learn(){        //父类方法
System.out.println("父类的learn()方法,人学习...");
}
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;
}
}
子类:
package duotai.upper;


public class Student extends Person {
private double score;


public Student() {
}


public Student(String name, int age, double score) {
super(name, age);
this.score = score;
}


@Override
public void learn() {        //子类方法重写,多态性的体现
System.out.println("学生学习...");
}


public double getScore() {
return score;
}


public void setScore(double score) {
this.score = score;
}
}
测试类:
package duotai.upper;


public class TestUpper {


public static void main(String[] args) {
Student stu=new Student("张三",20,83.5);   
Person per=stu;   // 向上转型    父类 父类对象=子类实例
per.say();
per.learn();
}
}
(2)向下转型:
package duotai.down;


public class TestDown {          


public static void main(String[] args) {      注意:向下转型前先要向上转型。
Person per=new Student("张三",20,83.5);   // 向上转型
Student stu=(Student)per;   // 向下转型    子类 子类对象=(子类)父类实例。
        stu.learn();
        }      
}

(3)instanceof关键字
在java中可以使用instanceof关键字判断一个对象是否属于一个类的实例
格式:
对象  instanceof  类     返回boolean类型
eg:
父类:
package instanceofdemo;


public class Person {
private String name;
private int age;


public Person() {
}


public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}


public void say() {
System.out.println("我是父类方法say(),姓名:" + this.name + ";年龄:" + this.age);
}



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;
}
}
农民类:
package instanceofdemo;


public class Farmer extends Person{


public Farmer() {
}

public Farmer(String name, int age) {
super(name, age);
}
public void plant() {
System.out.println("农民种地...");
}
}
学生类:
package instanceofdemo;


public class Student extends Person {
private double score;


public Student() {
}


public Student(String name, int age, double score) {
super(name, age);
this.score = score;
}
public void learn() {
System.out.println("学生学习...");
}


public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
测试类:
package instanceofdemo;


public class InstanceofDemo {


public static void main(String[] args) {
Student stu=new Student();
Farmer f=new Farmer();
method(null);
method(stu);
method(f);
System.out.println("********************");
Person p=new Student();
System.out.println(p instanceof Person);    // 判断是否是Person类型
System.out.println(p instanceof Student);  // 判断是否是由Student类的对象转换而来


}


public static void method(Person per){
if(per==null){
System.out.println("不能直接传递null!");
return;
}
if(per instanceof Student){
Student stu=(Student)per;
stu.learn();
}
if(per instanceof Farmer){
Farmer f=(Farmer)per;
f.plant();
}
}
}
(4)final关键字
在JAVA中声明类、属性和方法时,可以使用关键字final来修饰。       //final最后的,最终的
注意:
1.final修饰变量(成员变量或局部变量),则成为常量,只能赋值一次
   final  类型  variableName;
   修饰成员变量时,定义时同时给出初始值,而修饰局部变量时不做要求。
2.final修饰方法,则该方法不能被子类重写
    final 返回值类型  methodName(paramList)
   {
      …
   }


 3. final修饰类,则类不能被继承
     final class finalClassName{
         …
     }
eg:
package finaldemo;


public class Person{
   private final  String NAME="张三";      //final修饰属性
   
   public void testFinal(){
  final int a;
  a=5;
  System.out.println(a);
   }
   
   public final void walk(){      //final修饰方法
  System.out.println("人用两条腿走路~~~");
   }
}
三:抽象类与接口
3.1.用abstract修饰的类即为抽象类
  abstract class 抽象类名{
  }
  
3.2.抽象类不能被实例化,必须被继承,抽象方法必须被重写,生成它的子类。
由abstract修饰的方法就是抽象方法,抽象方法没有方法体。
抽象类不一定要包含抽象方法,若类中包含了抽象方法,则该类必须被定义为抽象类
如果一个子类没有实现抽象父类中所有的抽象方法,则子类也成为一个抽象类。
构造方法、静态方法、私有方法、final方法不能被声明为抽象的方法。
eg:

//父类

package abstractdemo;


public abstract  class Animal {
   private String name;
   private String food;
   
   public Animal(){
   }
   
   public Animal(String name, String food) {
 this.name = name;
 this.food = food;
   }


   public abstract void eat();   // 抽象方法只声明,不实现
}

//猫类

package abstractdemo;


public class Cat extends Animal {
private String fur;

public Cat(){
}

public Cat(String name, String food,String fur){
super(name,food);
this.fur=fur;
}

@Override   
public void eat() {
        System.out.println("小猫吃鱼...");
}

public String getFur() {
return fur;
}

public void setFur(String fur) {
this.fur = fur;
}

}

//test类

package abstractdemo;

public class TestAnimal {
    public static void main(String[] args) {
Animal animal1=new Cat();   // 由猫对象向上转型
animal2.eat();
}
}

注意:

package abstractdemo;


// 如果子类也是一个抽象类,则可以不用重写父类的抽象方法
public abstract class Tiger extends Animal{
    public abstract void run();
}

3.3.接口
接口(interface)是抽象方法和常量值的定义的集合。
接口是一种“标准”、“契约”。
从本质上讲,接口是一种特殊的抽象类,这种抽象类中只能包含常量和方法的定义,而没有变量和方法的实现。
接口的声明语法:
包括接口声明和 完整的接口声明: 接口体
[public] interface 接口名称[extends listOfSuperInterface] {  …  }
接口体包括常量定义和方法定义
常量定义: type NAME=value;  该常量被实现该接口的多个类共享; 具有public ,final, static的属性.
方法体定义:具有 public和abstract属性
接口的实现类
与抽象类一样,接口要使用也必须通过子类,子类通过implements关键字实现接口
一个类可以实现多个接口,在implements子句中用逗号分开
非抽象子类必须实现接口中定义的所有方法


实现格式:
class 子类 implements接口A,接口B…{
}
接口的使用规则:
接口中所有的方法都是public abstract。
在接口中声明方法时,不能使用static,final,synchronized,private,protected等修饰符。
一个接口可以继承自另一个接口。
java中不允许类的多继承,但允许接口的多继承。


接口中可以有数据成员,这些成员默认都是public static final

接口的用途
用处
(1)通过接口实现不相关类的相同行为,而无需考虑这些类之间的关系.
(2)通过接口指明多个类需要实现的方法
(3)通过接口了解对象的交互界面,而无需了解对象所对应的类
eg:
package interfacedemo;
/*
 * 散步接口
 * */
public interface Walk {
   public void walk();
}



package interfacedemo;
/**
 * 
 * 飞翔接口
 *
 */
public interface Fly {
   public static final int SPEED=200;    // 常量
   
   public abstract void fly();
   
}

package interfacedemo;


public class Bird implements Fly,Walk{         //继承俩接口


@Override
public void fly() {
System.out.println("小鸟飞翔...");
}


@Override
public void walk() {
System.out.println("小鸟散步...");

}
}


package interfacedemo;


public class Kite implements Fly{


@Override
public void fly() {
System.out.println("风筝飞翔...");
}


}
测试类:
package interfacedemo;


public class Test {


public static void main(String[] args) {
Fly f1=new Kite();
f1.fly();
Fly f2=new Bird();
f2.fly();
Walk w=new Bird();
        w.walk();
}
}
抽象类与接口:
eg:
package interfacedemo2;


public abstract class Animal {
}

//**********
package interfacedemo2;


import interfacedemo.Fly;


public interface ChildInterface extends ParentInterface,Fly{


}

//*************
package interfacedemo2;


import interfacedemo.*;


public class Dog extends Animal implements Walk{


@Override
public void walk() {
System.out.println("小狗散步...");
}
}

学习目标:
1.基本数据类型的包装类
2.String类、StringBuffer类、StringBuilder类
3.内部类

一、基本数据类型的包装类

(1)包装类、基本类

  例如:char  包装类:java.lang.Character

      int   包装类:java.lang,integer

   byte,short,long,flolat,double,boolean则为:java.lang.Byte    //首字母大写

 转换:

 基本数据类型转换为包装类:Integer intValue = new Integer(21);

    包装类转换为基本类型:Integer integerId=new Integer(25);

              int intId=integerId.intValue();

(2)自动装箱、拆箱

装箱:将基本数据类型包装为对应的包装类对象
拆箱:将包装类对象转换成对应的基本数据类型

eg:
package boxing;


public class IntegerDemo {


public static void main(String[] args) {
System.out.println("int的最大值:"+Integer.MAX_VALUE);
System.out.println("int的最小值:"+Integer.MIN_VALUE);
Integer a=100;   // 自动装箱
int b=a;   // 自动拆箱
String str="123";
int temp=Integer.parseInt(str);   // 将字符串转换为int
System.out.println(temp+5);
}
}

package boxing;


public class CharacterDemo {


public static void main(String[] args) {
   Character c='a';   // 自动装箱
   char x=c;  // 自动拆箱
   System.out.println("变为大写:"+Character.toUpperCase('a'));
   System.out.println("变为小写:"+Character.toLowerCase('Y'));
}
}
二:字符串相关类
1. String类
    (1) String代表字符串类型,字符串的内容本身不可改变,字符串存储于“字符串常量池”中。
    (2)String的两种实例化方式
         a:直接赋值法: eg:  String str=“Hello World”;

        b:通过new操作符实例化:
eg: String str=new String(“Hello World”);

(3)一个字符串就是一个String类的匿名对象。
         所谓匿名对象,就是在堆内存中开辟了空间,但在栈内存中并没有引用指向的对象。
(4)字符串常用方法
eg:package string;

public class StringMethod {


public static void main(String[] args) {
String str="中华人民共和国";
System.out.println(str.charAt(2));  // 根据索引位置获取字符串中的某个字符
        System.out.println(str.contains("人民"));   // 判断当前对象代表的字符串是否包含参数字符串内容
        System.out.println(str.indexOf("民共和"));
        // 将"abcde"的d变为大写
        String s1="abcdedx";
        System.out.println("从后往前找d:"+s1.lastIndexOf("d"));
        String s2="wxYz";
        System.out.println(s2.toUpperCase());
        System.out.println(s2.toLowerCase());
        System.out.println("中华人民共和国".substring(3));
        System.out.println("中华人民共和国".substring(3,6));
        String s3="   中     国     人  ";
        System.out.println("s3的长度:"+s3.length());
        System.out.println("删除了前后空格后的长度:"+s3.trim().length());
        System.out.println("*************************************");
        String country="中国,美国,俄罗斯,意大利,瑞典";
        String[] array=country.split(",");
        System.out.println("遍历拆分后的字符串:");
        for(String cou:array){
        System.out.print(cou+"  ");
        }
}
}
2. StringBuffer类:(线程安全)
  (1)StringBuffer代表可变的字符序列。
  StringBuffer称为字符串缓冲区,它的工作原理是:预先申请一块内存,存放字符序列,如果字符序列满了,会重新改变缓存区的大小,以容纳更多的字符序列。
 (2)StringBuffer是可变对象,这个是与String最大的不同(如果连续操作String对象,则会产生大量的“垃圾”,而且“断开-连接”很频繁。)
俩者比较:eg:
package stringbuffer;


public class StringBufferDemo {


public static void main(String[] args) {
StringBuffer sb=new StringBuffer();
sb.append("hello");
long start=System.currentTimeMillis();
for(int i=0;i<10000;i++){
sb.append(i);
}
long end=System.currentTimeMillis();
        System.out.println("使用StringBuffer耗时:"+(end-start));
        System.out.println(sb.length());
        
     //   sb.append("abc").append(false).append(12.5);
}
}
//********
package stringbuffer;


public class StringDemo {


public static void main(String[] args) {
String str="hello";
// 会产生大量的“垃圾”,而且不断“断开-连接”消耗性能
long start=System.currentTimeMillis();
        for(int i=0;i<10000;i++){
        str+=i;   // str=str+i
        }
        long end=System.currentTimeMillis();
        System.out.println("使用String耗时:"+(end-start));
        System.out.println(str.length());
}
}
eg2:
package stringbuffer;


public class StringBufferMethod {


public static void main(String[] args) {
StringBuffer sb=new StringBuffer();
sb.append("中国").append("香水").append("Java");
System.out.println("反转之前:");
System.out.println(sb.toString());
sb.reverse();   // 反转缓冲区的内容
System.out.println("反转之后:");
System.out.println(sb.toString());

StringBuffer sb2=new StringBuffer();
sb2.append(false).append(12.5).append("hello");
sb2.insert(1,true);   // 在索引为1处插入true
System.out.println(sb2);
}
}
3.StringBuilder类(线程不安全)
   StringBuilder和StringBuffer功能几乎是一样的,只是 StringBuilder是线程不安全的
三:内部类
1.在类的内部定义另一个类。如果在类Outer的内部再定义一个类Inner,此时Inner就称为内部类,而Outer则称为外部类。
   2.内部类的定义格式
public class 外部类{
//外部类成员
public class 内部类
      //内部类成员
}
  3.内部类在编译完成后也会产生.class文件,而文件名称则是”外部类名称$内部类名称.class”
**使用内部类的原因
好处:
1 可以方便地访问外部类的私有属性
2 减少了类文件编译后的产生的字节码文件的大小


缺点:使程序结构不清楚
1.成员内部类
成员内部类中不能定义static变量
成员内部类持有外部类的引用
在文件管理方面,成员内部类在编译完成后也会产生.class文件,而文件名称则是”外部类名称$内部类名称.class”
外部实例化成员内部类的格式:
 外部类.内部类  内部类对象=外部类实例.new 内部类();
eg:

package inner.member;

public class Outer {
   private String name="中国人";
   
   // 成员内部类
   class MemberInner{
  public void method(){
  System.out.println("内部类可以访问外部类的私有属性:"+name);
  }
   }
   
   public MemberInner getMemberInstance(){
  return new MemberInner();
   }
}

//test类

package inner.member;

public class TestMember {

public static void main(String[] args) {
Outer out=new Outer();
out.getMemberInstance().method();   // 通过在外部类中的成员方法中获取内部类对象
        
// 外部类.内部类  内部类对象=外部类实例.new 内部类();
Outer.MemberInner in=out.new MemberInner();
in.method();
}
}

2.静态内部类
如果一个内部类使用static声明,则此内部类就称为静态内部类,其实也相当于外部类。可以通过外部类.内部类来访问。
静态内部类不会持有外部类的引用,创建时可以不用创建外部类对象
静态内部类可以访问外部的静态变量,如果访问外部类的非static成员变量必须通过外部类的实例访问
外部实例化静态内部类对象的格式:
外部类.内部类  内部类对象= new  外部类.内部类();
eg:

package inner.staticdemo;
public class Outer {
   private String name="中国";
   private static int population=14;
   
   static class StaticInner{
  public void method(){
  System.out.println("静态内部类直接访问外部类的static属性:"+population);
  Outer out=new Outer();
  System.out.println("在静态内部类中通过外部类对象访问非static属性:"+out.name);
  }
   }
   
   public static StaticInner getStaticInner(){
  return new StaticInner();
   }
}

//test类

package inner.staticdemo;

public class TestStaticInner {

public static void main(String[] args) {
Outer.getStaticInner().method();
System.out.println("************************");
        Outer.StaticInner in=new Outer.StaticInner();
        in.method();
}
}

3.局域内部类
局域内部类是定义在一个方法中的内嵌类,所以类的作用范围仅限于该方法中,而类生成的对象也只能在该方法中使用。
   局域内部类不能包含静态成员
   特别注意:局域内部类要想访问包含其的方法中的参数,则方法中的参数前必须加上final关键字(JDK<=1.7)。
4.匿名内部类
如果一个内部类在整个操作中只使用一次的话,就可以定义为匿名内部类
没有名字的内部类,这是java为了方便我们编写程序而设计的一个机制,因为有时候有的内部类只需要创建一个它的对象就可以了,以后再不会用到这个类,这时候使用匿名内部类就比较合适

eg:

package inner.anonymity;

public interface Jumping {
    public void jump();
}

//test类

package inner.anonymity;

public class TestAnonumity {

public static void main(String[] args) {
Jumping j=new Jumping(){

@Override
public void jump() {
System.out.println("某人跳楼了...");
}

};
j.jump();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值