Java学习总结——面向对象(下)(接口,抽象类,内部类,String类等)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习总结——面向对象(下)(接口,抽象类,内部类,String类等)相关的知识,希望对你有一定的参考价值。
一:Object类
Object类时Java所有类的根基类(“又称为‘祖类’”)
若在Java中未用extends关键字指明基类,则 编译器默认为其基类是object类。
例:public class Person{}
其意义相当于public class Person extends Object{}
toString方法:
(1)Object类中定义有public String toString()方法,其返回值是String类型,描述当前对象的有关信息。
注意:如果直接打印某对象的引用,则默认会调用这个对象的toString()方法,默认打印的内容中包含这个引用所指向的内存地址。
例:
StringDemo类:
package tostring;
public class StringDemo {
private String name;
private String sex;
private int age;
public StringDemo() {
super();
}
public StringDemo(String name, String sex, int age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
public void say(){
System.out.println("我叫"+name+"性别"+sex+"年龄"+age);
}
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
TsetString测试类:
package tostring;
public class TestString {
public static void main(String[] args) {
StringDemo str=new StringDemo();
System.out.println(str);
}
}
可见打印的是str的地址
(2)可以根据需要(例要打引用所指向的内容)在用户自定义类中重写toString()方法。
例:
toString类:
package tostring;
public class StringDemo {
private String name;
private String sex;
private int age;
public StringDemo() {
super();
}
public StringDemo(String name, String sex, int age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "name:"+name+" age:"+age+" sex:"+sex;
}
}
TestString测试类:
package tostring;
public class TestString {
public static void main(String[] args) {
StringDemo str=new StringDemo("王刚","男",17);
System.out.println(str);
}
}
结果为:name:王刚 age:17 sex:男
可见打印结果为:str地址中所指向的内容
equals()方法:
(1)Object类中定义有public boolean equals(Object obj) 方法,提供定义对象是否“相等”的逻辑。
(2)Object的equals方法定义为:x.equals(y),当x和y指向同一个地址时返回true,否则返回false。
(3)String类中已经重写了equals(Object obj)方法,重写后的方法比较的是两个字符串的”内容”是否一样(注意:==比较对象的引用)
(4)可以根据需要在用户自定义类型中重写equals方法。
例1:
Cat类:
package equalsdemo;
public class Cat {
String color;
int height,wight;
public Cat() {
super();
}
public Cat(String color, int height, int wight) {
super();
this.color = color;
this.height = height;
this.wight = wight;
}
}
TestCat类:
package equalsdemo;
public class TestCat {
public static void main(String[] args) {
Cat cat1=new Cat("白色",1,1);
Cat cat2=new Cat("白色",1,1);
int x,y=1;
x=1;
System.out.println(x==y);
System.out.println("cat1与cat2相等吗?"+cat1.equals(cat2));
System.out.println("cat1==cat2的结果是:"+(cat1==cat2));
}
}
结果为:x与y相比:true
cat1与cat2相等吗?false
cat1==cat2的结果是:false
由结果可知:因为cat1和cat2都是新new出来的并且没有重写equals方法,由于他们堆内存中占据的空间不同,所以他们不会相等,cat1和cat2都是堆内存中两只猫的引用对象里边装着可以找到只猫的地址,但由于两只猫的内容存储在不同空间内,所以cat1和cat2装着的地址永远不会相同,所以c1==c2也不会相等
例2:(重写equals方法和字符串比较)
Dog类:
package equalsdemo;
public class Dog {
int color;
int height;
public Dog() {
super();
}
public Dog(int color, int height) {
super();
this.color = color;
this.height = height;
}
@Override
public boolean equals(Object obj) {
if(obj==null){
return false;
}else if(obj instanceof Dog){
Dog dog=(Dog)obj;
if(dog.color==this.color && dog.height==this.height){
return true;
}
}
return false;
}
}
TestDog类:
package equalsdemo;
public class TestDog {
public static void main(String[] args) {
String str1=new String("Hello");
String str2=new String("Hello");
Dog dog1=new Dog();
Dog dog2=new Dog();
System.out.println("字符串相比较:");
System.out.println("str1与str2一样吗?"+str1.equals(str2));
System.out.println("用==的结果是:"+(str1==str2));
System.out.println("_______________________-");
System.out.println("重写equals方法得:");
System.out.println("dog1和dog2是一条狗吗?"+dog1.equals(dog2));
System.out.println("用==的结果是:"+(dog1==dog2));
}
}
打印结果:字符串相比较:
str1与str2是一样吗?true
用==的结果是:false
_______________________-
重写equals方法得:
dog1和dog2是一条狗吗?true
用==的结果是:false
由结果可得:当equals方法重写后,dog1==dog2输出为false,因为比较的是两个引用中的内容,这两个引用中的内容当然不相等,而且永远不会相等,所一输出为false;但dog1.equals(dog2)输出结果为true,因为我们在Dog类中重写了equals方法,改变了这个方法的默认实现,改成了只要这两个对象只要真实存在,并且他们的颜色(color)和身高(height)一样,那么这两只狗我们就认为他们完全相等;比较字符串:str1==str2结果为false,因为这里比较的是两个对象的引用,故他们一定不会相等,但str1.equals(str2)结果为true,因为String中重写了从Object类所继承的equals方法,改变了这个方法的默认实现。
*总结:equals方法重写时设计规则:
(1)自反性:对任意引用值X,x.equals(x)的返回值一定是true;
(2)对称性:对于任何引用值x,y当且仅当y.equals(x)时返回值是true时x.equals(y)返回值一定是true;
(3)传递性:如果x.equals(y)=true,y.equals(z)=true,则x.equals(z)=true;
(4)一致性:如果参与比较的对象没有任何改变,则对象的比较结果也不应该有任何改变;
(5)非空性:任何对象的引用值X, x.equals(null)的返回值一定是false
多态性
意义:是由封装性和继承性引出的面向对象程序设计语言的另一特征。(封装是为了保护属性的一种操作,继承是为了扩展类的功能)
多态的体现:
*从方法角度:方法的重载与重写;
(1)方法重写(overloading):子类根据需要重写父类的方法;
(2)方法重载(override):传入的参数不同完成的功能也不同
*从对象的角度来看:
(1)向上转型:子类对象转化为父类对象,子类对象->父类对象 (程序会自动完成)
格式:父类 父类对象=子类实例
注意:向上转型后,因为操作的是父类对象,所以无法找到在子类中定义的新方法;但如果子类重写了父类的某个方法,则调用的是重写后的方法。
例1:
Person类:
package MethodDuotai;
public class Person {
String name;
int age;
String sex;
public Person() {
super();
}
public Person(String name, int age){
super();
this.name = name;
this.age = age;
}
public Person(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
public void say(){
System.out.println("我叫"+name+"年龄"+age+"性别"+sex);
}
}
Student类:
package MethodDuotai;
public class Student extends Person{
private double score;
public Student() {
super();
}
public Student(String name, int age, String sex,double score) {
super(name,age,sex);
this.score = score;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public void say(){
System.out.println("我叫"+name+"年龄"+age+"性别"+sex+"分数"+score);
}
}
TestPerson类:
package MethodDuotai;
public class Testperson {
public static void main(String[] args) {
Person per=new Person("张三",12,"男");
Student stu=new Student("张三",12,"男",95.7);
per.say();
stu.say();
}
}
结果为:我叫张三年龄12性别男
我叫张三年龄12性别男分数95.7
*红色标记为方法的重载;蓝色标记为方法的重写
向下转型:父类对象->子类对象 (必须明确的指明要转型的子类类型)
格式:子类 子类对象=(子类)父类实例
注意:向下转型前必须向上转型
例2(在例1的基础上):
package MethodDuotai;
public class Testperson {
public static void main(String[] args) {
Person per=new Person("张三",12,"男");
Student stu=new Student("张三",12,"男",95.7);
per.say();
stu.say();
System.out.println();
System.out.println("__向上转型_____");
per=new Student("张三",12,"男",95.7);
//per.walk(); //报错
per.say();
System.out.println("__向下转型______");
stu=(Student)per;
per.say();
}
}
结果为:
我叫张三年龄12性别男
我叫张三年龄12性别男分数95.7
__向上转型_____
我叫张三年龄12性别男分数95.7
__向下转型______
我叫张三年龄12性别男分数95.7
*(1)由此可见向上转型后父类被重写后的方法
*(2)向上转型后无法访问子类的新方法
instanceof关键字
在Java中利用instanceof关键字判断一个对象是否属于一个类的实例;
格式:对象 instanceof 类 à返回boolean类型
例:
Animal动物类:
package instanceofdemo;
public class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(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;
}
}
Dog狗类:
package instanceofdemo;
public class Dog extends Animal{
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
public void plant() {
System.out.println("小狗啃骨头");
}
}
Cat猫类:
package instanceofdemo;
public class Cat extends Animal {
private String color;
public Cat() {
}
public Cat(String name, int age, String score) {
super(name, age);
this.color = color;
}
public void learn() {
System.out.println("小猫吃鱼~");
}
public String getScore() {
return color;
}
public void setScore(String color) {
this.color = color;
}
}
InstanceofDemo测试类:
package instanceofdemo;
public class InstanceofDemo {
public static void main(String[] args) {
Dog dog=new Dog();
Cat cat=new Cat();
method(null);
method(dog);
method(cat);
System.out.println("********************");
Animal an=new Dog();
System.out.println(an instanceof Animal); // 判断是否是Animal类型
System.out.println(an instanceof Dog); // 判断是否是由Dog类的对象转换而来
}
public static void method(Animal an){
if(an==null){
System.out.println("不能直接传递null!");
return;
}
if(an instanceof Dog){
Dog dog=(Dog)an;
dog.plant();
}
if(an instanceof Cat){
Cat cat=(Cat)an;
cat.learn();
}
}
}
结果为:
不能直接传递null!
小狗啃骨头
小猫吃鱼~
********************
true
true
红色即为instanceof关键字的用法
final关键字
*在Java中声明类,属性,方法是可以使用final关键字来修饰
注意:(1)final修饰变量,则此变量(成员变量或局部变量)成为常量,只能赋值一次,修饰成员变量时必须赋初值
格式:final 类型 变量名(variableName);
例:public class finaldemo {
final int age=15;
} //修饰成员变量必须赋初值
final修饰类赋,则此类不能被继承;
final修饰的方法,子类不能重写;
三.抽象类与接口
1.抽象类:用abstract修饰的类即为抽象类
(1)格式:abstract class 抽象类名{
}
(2)抽象类不能被实例化,必须被继承,抽象方法必须被重写,生成它的子类
2.抽象方法:用abstract修饰方法即为抽象方法,抽象方法没有方法体;
注意:
(1)抽象类中不一定有抽象方法,但有抽象方法的一定是抽象类
(2)如果子类没有实现抽象类中的所有抽象方法,则该子类也成为一个抽象类;
(3)构造方法,静态方法,私有方法不能被定义为抽象方法
例:
AbstractPerson抽象类:
package abstractdemo;
public abstract class Person {
String name;
String sex;
public Person() {
super();
}
public Person(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
public abstract void eat();
}
Student实现类:
package abstractdemo;
public class Student extends Person{
private int age;
public Student() {
super();
}
public Student(String name,String sex,int age) {
super(name,sex);
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat() {
System.out.println("姓名为"+name+"性别椒"+sex+"年龄为"+age+"的学生正在吃东西");
}
}
TestPerson测试类:
package abstractdemo;
public class TestPerson {
public static void main(String[] args) {
Student stu=new Student("占三","男",18);
stu.eat();
}
}
结果为:姓名为占三性别椒男年龄为18的学生正在吃东西
例(为实现父类中的抽象方法):
package abstractdemo;
public abstract class Programmer extends Person{
public void coding(){
System.out.println("程序员写程序");
}
}
可以看出还是抽象类
3.接口(interface)(重点)
(1)接口是抽象方法和常量值定义发的集合
(2) 接口是一种“标准”、“契约”。
(3)从本质上讲,接口是一种特殊的抽象类,这种抽象类中只能包含常量和方法的定义,而没有变量和方法的实现
(4)接口的声明语法:
·包括接口声明和接口体
(5)完整的接口声明:
[public] interface 接口名称[extends listOfSuperInterface] { … }
#接口体包括常量定义和方法定义
#常量定义: type NAME=value; 该常量被实现该接口的多个类共享; 具有public ,final, static的属性.
注意:常量名必须大写
#方法体定义:具有 public和abstract属性
(6)接口的实现类:
与抽象类一样,接口要使用也必须通过子类,子类通过implements关键字实现接口
一个类可以实现多个接口,在implements子句中用逗号分开
非抽象子类必须实现接口中定义的所有方法
实现格式:
class 子类 implements接口A,接口B…{
}
(7)接口的使用规则:
接口中所有的方法都是public abstract。
在接口中声明方法时,不能使用static,final,synchronized,private,protected等修饰符。
一个接口可以继承自另一个接口。
java中不允许类的多继承,但允许接口的多继承。
接口中可以有数据成员,这些成员默认都是public static final
(8)接口的用法:
# 通过接口实现不相关类的相同行为,而无需考虑这些类之间的关系.
# 通过接口指明多个类需要实现的方法
# 通过接口了解对象的交互界面,而无需了解对象所对应的类
例:
Animal动物接口:
package interfacedemo;
public interface Animal {
int ID=1;
void breath();
void shout();
}
Run接口:
package interfacedemo;
public interface Run {
void run();
}
Dog实现类:
package interfacedemo;
public class Dog implements Animal{
public void breath() {
System.out.println("小狗在呼吸");
}
public void shout() {
System.out.println("小狗在叫:汪汪");
}
}
Cat实现类:
package interfacedemo;
public class Cat implements Animal,Run{
private String name;
public Cat() {
super();
}
public Cat(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void breath() {
System.out.println("名为:"+name+"的猫在呼吸");
}
public void shout() {
System.out.println("猫在叫:喵喵");
}
public void run() {
System.out.println("小猫在跑");
}
}
TestAnimal测试类:
package interfacedemo;
public class TestAnimal {
public static void main(String[] args) {
Dog dog=new Dog();
Cat cat=new Cat("Tom");
dog.breath();
dog.shout();
System.out.println("*************");
cat.breath();
cat.run();
cat.shout();
}
}
接口Fly继承接口:
package interfacedemo;
public interface Fly extends Animal,Run {
}
结果为:小狗在呼吸
小狗在叫:汪汪
*************
名为:Tom的猫在呼吸
小猫在跑
猫在叫:喵喵
*红色标记为接口
*例中实现了接口的用法
*例中绿色标记可以看出接口可以实现多继承
四.基本数据类型的包装类
1. Java语言针对所有的基本数据类型都提供了对应的包装类。
基基本数据类型 | 包装类 |
byte(字节) | java.lang.Byte |
char(字符) | java.lang.Character |
short(短整型) | java.lang.Short |
int(整型) | java.lang.Integer |
long(长整型) | java.lang.Long |
float(浮点型) | java.lang.Float |
double(双精度) | java.lang.Double |
boolean(布尔) | java.lang.Boolean |
2.(1)基本数据类型转换为包装类
eg:Integer intValue = new Integer(21);
(2)包装类转换成基本类型
eg:Integer integerId=new Integer(25);
int intId=integerId.intValue();
3. JDK5.0中为基本数据类型提供了自动装箱(boxing)、拆箱(unboxing)功能:
(1)装箱:将基本数据类型包装为对应的包装类对象
(2)拆箱:将包装类对象转换成对应的基本数据类型
Eg: Integer intObject = 5;
int intValue = intObject;
包装类并不是用来取代基本数据类型的
例1:
CharacterDemo类:
package boxing;
public class CharacterDemo {
public static void main(String[] args) {
Character c='a'; // 自动装箱
char x=c; // 自动拆箱
System.out.println("变为大写:"+Character.toUpperCase('b'));
System.out.println("变为小写:"+Character.toLowerCase('Z'));
}
}
结果为:变为大写:B
变为小写:z
例中红色标记为自动拆箱与装箱,绿色标记为Character类中基本方法的应用
例2:
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="456";
int temp=Integer.parseInt(str); // 将字符串转换为int
System.out.println(temp+7);
}
}
结果为:int的最大值:2147483647
int的最小值:-2147483648
128
例中红色标记为自动拆箱与装箱,绿色标记为Integer类中方法的应用
*字符串转化为int型特别注意:
例:String str=“123”;
System.out.println(str+5);
结果为:1235
*若想将str转化为int型:
int temp=Integer.parstInt(str);
System.out.println(str+5);
结果为:128
字符串相关类
1. String类
(1) String代表字符串类型,字符串的内容本身不可改变,字符串存储于“字符串常量池”中。
(2)String的两种实例化方式
a:直接赋值法:
eg: String str=“Hello World”;
**直接赋值法String 内存图
b:通过new操作符实例化:
eg: String str=new String(“Hello World”);
下面是通过new操作符实例化String的内存图
(3)一个字符串就是一个String类的匿名对象。
所谓匿名对象,就是在堆内存中开辟了空间,但在栈内存中并没有引用指向的对象。
(4)字符串常用方法
1.public String(byte[] bytes)
使用平台的默认字符集解码,将字节数组转换为字符串
2.public String(byte[] bytes,Charset charset)
使用指定字符集解码,将字节数组转换为字符串
3.public char charAt(int index)
根据索引位置获取字符串中的某个字符
4.public boolean contains(CharSequence s)
判断当前对象代表的字符串是否包含参数字符串内容
5.public boolean equals(Object anObject)
判断字符串内容是否相同
6.public byte[] getBytes()
将字符串转换为字节数组
7.public int indexOf(String str)
返回参数字符串在当前字符串中的索引位置
9.public int lastIndexOf(String str)
从后往前找参数字符串,返回参数字符串在当前字符串中的索引位置
10.public int length()
返回当前字符串的长度
11.public String toLowerCase()
将字符串转换为小写
12.public String toUpperCase()
将字符串转换为大写
13.public char[] toCharArray()
将字符串转换为字符数组
14.public String substring(int beginIndex)
从beginIndex索引位置开始,到字符串末尾,截取字符串
15.public String substring(int beginIndex,int endIndex)
从beginIndex索引位置开始,到endIndex-1,截取字符串
16.public String trim()
返回一个字符串,这个字符串删除了前导和尾随空格
17.public String[] split(String regex)
通过指定的正则表达式拆分字符串,将拆分后的结果作为一个字符串数组返回
例1:
package stringdemo;
public class StringMethod {
public static void main(String[] args) {
String str="我是中国人中华";
System.out.println("字符串中索引位置2的字符是:"+str.charAt(2));
System.out.println("字符串中“中”字的索引为:"+str.indexOf("中"));
System.out.println("字符串中倒叙找“中”的索引为: "+str.lastIndexOf("中"));
System.out.println("字符 串的长度是:"+str.length());
System.out.println("根据索引位置截取的字符 串是:"+str.substring(4));
System.out.println("字符串中是否包含“中国人”:"+str.contains("中国人"));
System.out.println("由索引截取字符串,起止:"+str.substring(2, 5));
String str1="×××";
String str2="我是中国人中华";
System.out.println("字符串str中的内容是否与str1中的相同:"+str.equals(str1));
System.out.println("字符串str中的内容是否与str2中的相同:"+str.equals(str2));
String str3="abHvhFHn";
System.out.println("将字符串中的大写转换为小写:"+str3.toLowerCase());
System.out.println("将字符串中的小写转化为大写:"+str3.toUpperCase());
String str4="aufafvvidsgd";
char[] a=str4.toCharArray();
System.out.println("将字符串转化为字符串数组为:");
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
System.out.println();
String str5=" zhogn ";
System.out.println("去除字符串前面和后面的空格为:"+str5.trim());
String str6="12345668";
byte[] b=str6.getBytes();
System.out.println("将字符串转换为字节数组为:"+b);
String s=new String(b);
System.out.println("将字节数组转换为字符串为:"+s);
String score="56,67,78,56,32,98.76";
String[] sco=score.split(",");
System.out.println("按照既定 的规则拆分字符串:");
for( String x:sco){
System.out.print(x+" ");
}
}
}
结果为:
字符串中索引位置2的字符是:中
字符串中“中”字的索引为:2
字符串中倒叙找“中”的索引为: 5
字符 串的长度是:7
根据索引位置截取的字符 串是:人中华
字符串中是否包含“中国人”:true
由索引截取字符串,起止:中国人
字符串str中的内容是否与str1中的相同:false
字符串str中的内容是否与str2中的相同:true
将字符串中的大写转换为小写:abhvhfhn
将字符串中的小写转化为大写:ABHVHFHN
将字符串转化为字符串数组为:
a u f a f v v i d s g d
去除字符串前面和后面的空格为:zhogn
将字符串转换为字节数组为:[[email protected]
将字节数组转换为字符串为:12345668
按照既定 的规则拆分字符串:
56 67 78 56 32 98.76
例 2:
package stringdemo;
public class String02 {
public static void main(String[] args) {
String str1="Hello";
String str2="Hello";
System.out.println(str1==str2);
System.out.println(str1.equals(str2));
String str3=new String("Hello");
System.out.println(str1.equals(str3));
}
}
结果为:true
true
True
具体原因equals中已经解释
String方法应用练习:
1.编写程序,统计出字符串“want you to know one thing”
中字母n和字母o的出现次数
2.分别截取字符串" ABCmnyCW123 "中的"CmnyCW123"部分和"CW123"部分。
提示:会使用到indexOf(xx) lastIndexOf(xxx) substring(xxx) trim()方法。
解析1:
package stringdemo;
public class StringArrray {
public static void main(String[] args) {
String str="want you to know one things";
char[] c=str.toCharArray();
int n=0;
int o=0;
for(int i=0;i<c.length;i++){
if(c[i]=='n'){
n++;
}
if(c[i]=='o'){
o++;
}
}
System.out.println("出现n的次数:"+n);
System.out.println("出现o的次数:"+o);
}
}
结果为:出现n的次数:4
出现o的次数:4
解析2:
package stringdemo;
public class Substring {
public static void main(String[] args) {
String str=" ABCmnyCW123 ";
int s=str.indexOf("C");
System.out.println("截取后的结果是:"+str.substring(s).trim());
int c=str.lastIndexOf("C");
System.out.println("第二次截取后的结果是:"+str.substring(c).trim());
}
}
结果为:截取后的结果是:CmnyCW123
第二次截取后的结果是:CW123
StringBuffer类
StringBuffer代表 可变的字符序列(StringBuffer称为字符缓冲区),其工作原理为:预先申请一块内存,存放字符序列,如果字符序列满了会重新 扩展缓存区的大小,以容纳更多的字符序列。
StringBuffer是可变换对象,这是与String最大的不同。(如果连续操作String对象,则会产生大量的“垃圾”,而且“断开-连接”很频繁。
例(String应用):
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);
}
}
运行结果为:
反转之前:
中国香水Java
反转之后:
avaJ水香国中
ftruealse12.5hello
例2;
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());
}
}
运行结果为:使用StringBuffer耗时:6
38895
3.StringBuilder类
StringBuilder和StringBuffer功能几乎是一样的,只是 StringBuilder是线程不安全的
内部类
1.在类的内部定义另一个类。如果在类Outer的内部再定义一个类Inner,此时Inner就称为内部类,而Outer则称为外部类。
2.内部类的定义格式:
Public class 外部类{
外部类成员
Public class 内部类{
内部类成员
}
}
内部类在编译完成后也会产生.class文件,而文件名称则是”外部类名称$内部类名称.class”
使用内部类的原因:心脏属于人类的某个部分:但心脏不能简单用属性或者方法表示一个心脏,因为心脏也有自己的属性和行为,所以需要写在人类的内部
使用内部类的原因:(1)好处:可以方便地访问外部类的私有属性;减少了类文件编译后的产生的字节码文件的大小。(2)缺点:使程序结构不清楚
内部类分类(重点):
成员内部类
*成员内部类中不能定义static变量
*成员内部类持有外部类的引用
*在文件管理方面,成员内部类在编译完成后也会产生.class文件,而文件名称则是”外部类名称$内部类名称.class”
*外部实例化成员内部类的格式:
外部类.内部类 内部类对象=外部类实例.new 内部类()
例1(成员内部类):
成员内部类:
package memberclass;
public class Outer {
private int num=5;
public void test(){
Inner inner=new Inner();
inner.show();
}
class Inner{
public void show(){
System.out.println("num="+num);
}
}
}
测试成员内部类:
package memberclass;
public class TestMemclass {
public static void main(String[] args) {
Outer outer=new Outer();
outer.test();
}
}
结果:num=5
例2:
package memberclass;
public class Outer02 {
private String name="张三";
class Inner{
public void say(){
System.out.println("我叫"+name);
}
}
public Inner getInner(){
return new Inner();
}
}
TestInner类:
package memberclass;
public class TestInner {
public static void main(String[] args) {
// 通过在外部类中的成员方法中获取内部类对象
Outer02 outer=new Outer02();
outer.getInner().say();
// 外部类.内部类 内部类对象=外部类实例.new 内部类();
Outer02.Inner inner=outer.new Inner();
inner.say();
}
}
结果为:我叫张三
我叫张三
例中详细的做出了访问成员内部类的方法
静态内部类:
*如果一个内部类使用static声明,则此内部类就称为静态内部类,其实也相当于外部类。可以通过外部类.内部类来访问。
*静态内部类不会持有外部类的引用,创建时可以不用创建外部类对象
*静态内部类可以访问外部的静态变量,如果访问外部类的非static成员变量必须通过外部类的实例访问
*外部实例化静态内部类对象的格式:
外部类.内部类 内部类对象= new 外部类.内部类();
例:
静态内部类:
package staticclass;
public class Outer {
private String name="张三丰";
private static int age=22;
static class Inner{
public void say(){
System.out.println("访问外部了静态变量:age="+age);
Outer outer=new Outer();
System.out.println("访问外部类非静态变量:"+outer.name);
}
}
}
测试静态内部类:
package staticclass;
public class TestInner {
public static void main(String[] args) {
Outer.Inner inner=new Outer.Inner();
inner.say();
}
}
结果:访问外部了静态变量:age=22
访问外部类非静态变量:张三丰
局域内部类:
*局域内部类是定义在一个方法中的内嵌类,所以类的作用范围仅限于该方法中,而类生成的对象也只能在该方法中使用。
* 局域内部类不能包含静态成员
* 特别注意:局域内部类要想访问包含其的方法中的参数,则方法中的参数前必须加上final关键字(JDK<=1.7)。
例:
局域内部类:
package localclass;
public class Outer {
private int age=23;
private String name="希特勒";
public void say(int x){
class Inner{
public void talk(){
System.out.println("直接访问外部类变量此人age:"+age+"name:"+name);
System.out.println("访问外部类方法传参:"+x);
}
}
Inner inner=new Inner();
inner.talk();
}
}
测试局域内部类:
package localclass;
public class TestLocal {
public static void main(String[] args) {
Outer outer=new Outer();
outer.say(27);
}
}
结果:直接访问外部类变量此人age:23name:希特勒
访问外部类方法传参:27
匿名内部类:
*如果一个内部类在整个操作中只使用一次的话,就可以定义为匿名内部类
*没有名字的内部类,这是java为了方便我们编写程序而设计的一个机制,因为有时候有的内部类只需要创建一个它的对象就可以了,以后再不会用到这个类,这时候使用匿名内部类就比较合适
例:
动物接口:
package anonumityclass;
public interface Animal {
void shout();
}
测试匿名内部类:
package anonumityclass;
public class TestAnonumity {
public static void main(String[] args) {
//定义匿名内部类作为参数传递给animalShout()方法
animalShout(new Animal(){
//实现shout方法
public void shout(){
System.out.println("喵喵~~~~~");
}
});
}
//定义静态方法animalShout
public static void animalShout(Animal an){
an.shout();//调用传入对象an的shout()方法
}
}
小结(以一个作业题结束):
(1)定义以下这些接口和类,并完成相关属性和方法的声明和调用.数据类型,参数列表,返回值类型等请根据题目需要自行定义.
学习接口Learning(包含方法: 预习preLearn,上课lessons,复习reveiw)
喝酒接口Drinking(包含方法: 喝酒drink, 吐throwup,耍酒疯playMad)
抽象类Person(包含属性:姓名,性别,年龄; 抽象方法:谈恋爱love)
学生Student是人,得会学习,但不能喝酒(因为会使大脑变笨);他们还有自己的学校(school),还喜欢和朋友聊微信(chatting).
公务员Officer是人,不用学习,但经常需要喝酒应酬;他们还得经常开一些无聊的会议(meeting).
程序猿Programmer,是人,必须经常学习,较少社交所以不喝酒;他们特别喜欢写代码(coding),和修bug(debuging).
(2)在场景类Client中定义一个方法method1,在形参和实参上体现对象的多态性,在方法中进行调用,如果对象的实际类型是学生,
就和朋友聊微信;如果是公务员,就去开会;如果是程序猿,就去写代码和修bug.
(3)直接打印一个学生对象,就能以下面格式来输出:
学生信息: 姓名:张三,性别:男,年龄:20,学校:北大.
(4)如果两个学生的姓名、性别、年龄、学校一样,则认为这两个学生“相等”。
学习接口:
package studyDemo;
public interface Learning {
void preLearn();
void lessons();
void reveiw();
}
喝酒接口:
package studyDemo;
public interface Drinking {
void drink();
void throwup();
void palyMad();
}
Person抽象类:
package studyDemo;
public abstract class Person{
String name;
int age;
String sex;
public Person() {
super();
}
public Person(String name, int age, String sex) {
super();
this.name= name;
this.age = age;
this.sex = sex;
}
public abstract void love();
}
学生Student实现类:
package studyDemo;
public class Student extends Person implements Learning{
private String shoolName;
public Student() {
super();
}
public Student(String shoolName,String name,int age,String sex) {
super(name,age,sex);
this.shoolName = shoolName;
}
public void preLearn() {
System.out.println(name+"同学正在预习中~~");
}
public void lessons() {
System.out.println("上课了"+name+"同学上课去了");
}
public void reveiw() {
System.out.println("上课完毕,回家复习~~");
}
public void chating(){
System.out.println(shoolName+"的学生"+name+"和朋友聊微信中~~");
}
public String getShoolName() {
return shoolName;
}
public void setShoolName(String shoolName) {
this.shoolName = shoolName;
}
public void love() {
// TODO Auto-generated method stub
System.out.println(name+"是位"+sex+"生今年"+age+"岁了,在和对面男生谈恋爱~~");
}
@Override
public boolean equals(Object obj) {
if(this==obj){
System.out.println("$学生自己比自己,当然是同一人!");
return true;
}
if(obj==null){
System.out.println("$传入参数为null,无法比较!");
return false;
}
if(!(obj instanceof Student)){
System.out.println("$传递的不是学生对象!");
return false;
}
Student stu=(Student)obj;
if(this.name!=null && this.name.equals(stu.name) && this.age==stu.age && this.sex==stu.sex){
return true;
}
return false;
}
public String toString() {
// TODO Auto-generated method stub
return "学生 [姓名:" + name + ", 年龄:" + age + ", 性别:" + sex
+ "]";
}
}
程序员实现类:
package studyDemo;
public class Programmer extends Person implements Learning{
public Programmer(){
}
public Programmer(String name,int age,String sex){
super(name,age,sex);
}
public void preLearn() {
// TODO Auto-generated method stub
System.out.println("名为"+name+"的程序员正在预习~");
}
public void lessons() {
// TODO Auto-generated method stub
System.out.println(name+"正在上课中~");
}
public void reveiw() {
// TODO Auto-generated method stub
System.out.println("上课完毕,回家复习~");
}
public void love() {
// TODO Auto-generated method stub
System.out.println(name+"是位"+sex+"程序员,今年"+age+"岁正在和隔壁女孩谈恋爱~");
}
public void coding(){
System.out.println(name+"程序员特别喜欢写代码~");
}
public void debuging(){
System.out.println(name+"也喜欢修电脑Bug");
}
public String toString() {
// TODO Auto-generated method stub
return "程序员 [姓名:" + name + ", 年龄:" + age + ", 性别:" + sex
+ "]";
}
}
公务员实现类:
package studyDemo;
public class Officer extends Person implements Drinking{
public Officer(){
super();
}
public Officer(String name, int age, String sex) {
// TODO Auto-generated constructor stub
super(name,age,sex);
}
public void drink() {
// TODO Auto-generated method stub
System.out.println(name+"正在应酬喝酒~");
}
public void throwup() {
// TODO Auto-generated method stub
System.out.println("他喝多吐了");
}
public void palyMad() {
// TODO Auto-generated method stub
System.out.println("这位"+sex+"公务员,名叫"+name+"喝多了,正在耍酒疯~");
}
public void love() {
// TODO Auto-generated method stub
System.out.println("这位"+age+"的公务员正在和对面的女孩谈恋爱~");
}
public void meeting(){
System.out.println("公务员"+name+"在无聊的开会中~");
}
public String toString() {
// TODO Auto-generated method stub
return "公务员 [姓名:" + name + ", 年龄:" + age + ", 性别:" + sex
+ "]";
}
}
Client情景测试类:
package studyDemo;
public class Client {
public static void main(String[] args) {
System.out.println("学生模块:");
Student stu=new Student("西部开源","李芳",18,"女");
stu.preLearn();
stu.lessons();
stu.reveiw();
stu.chating();
stu.love();
System.out.println("__toString应用___________-");
System.out.println(stu);
System.out.println("**********************");
System.out.println("公务员模块:");
Officer cer=new Officer("王磊",35,"男");
cer.drink();
cer.throwup();
cer.palyMad();
cer.meeting();
cer.love();
System.out.println("____toString应用____________-");
System.out.println(cer);
System.out.println("**********************");
System.out.println("程序员模块:");
Programmer pro=new Programmer("冯超",24,"男");
pro.preLearn();
pro.lessons();
pro.reveiw();
pro.coding();
pro.debuging();
pro.love();
System.out.println("______toString应用____________");
System.out.println(pro);
System.out.println("***********************");
System.out.println("学生比较模块:");
System.out.println("________equals比较运用___________");
Student stu1=new Student("西部开源","张三", 10,"男");
Student stu2=new Student("西部开源","张三", 10,"男");
Student stu3=new Student("西部开源","李四", 10,"男");
Student stu4=new Student("西安交大","张三", 25,"男");
stu1.equals(null);
stu1.equals(pro);
stu1.equals(stu1);
boolean flag1=stu1.equals(stu2);
if(flag1){
System.out.println("学生1与学生2是同一人");
}else{
System.out.println("学生1与学生2不是同一人");
}
System.out.println(stu1.equals(stu3)?"学生1与学生3是同一人":"学生1与学生3不是同一人");
System.out.println(stu1.equals(stu4)?"学生1与学生4是同一人":"学生1与学生4不是同一人");
System.out.println(stu2.equals(stu3)?"学生2与学生3是同一人":"学生2与学生3不是同一人");
System.out.println(stu2.equals(stu4)?"学生2与学生4是同一人":"学生2与学生4不是同一人");
System.out.println(stu3.equals(stu4)?"学生3与学生4是同一人":"学生3与学生4不是同一人");
System.out.println("************************");
System.out.println("_______instanceof的应用________");
System.out.println("——传入为空时——:");
interfaceofDemo(null);
System.out.println();
System.out.println("——传入为学生时——:");
interfaceofDemo(stu);
System.out.println();
System.out.println("——传入为程序员时——:");
interfaceofDemo(pro);
System.out.println();
System.out.println("——传入为公务员时——:");
interfaceofDemo(cer);
System.out.println();
System.out.println("————————————作 业 完 结——————————————————");
}
public static void interfaceofDemo(Person per){
if(per==null ){
System.out.println("传入为空:停止");
return;
}
if(per instanceof Student){
Student stu=(Student)per;
stu.lessons();
stu.preLearn();
stu.reveiw();
}
if(per instanceof Programmer){
Programmer pro=(Programmer)per;
pro.coding();
pro.debuging();
}
if(per instanceof Officer){
Officer cer=(Officer)per;
cer.meeting();
}
}
}
运行结果:
学生模块:
李芳同学正在预习中~~
上课了李芳同学上课去了
上课完毕,回家复习~~
西部开源的学生李芳和朋友聊微信中~~
李芳是位女生今年18岁了,在和对面男生谈恋爱~~
__toString应用___________-
学生 [姓名:李芳, 年龄:18, 性别:女]
**********************
公务员模块:
王磊正在应酬喝酒~
他喝多吐了
这位男公务员,名叫王磊喝多了,正在耍酒疯~
公务员王磊在无聊的开会中~
这位35的公务员正在和对面的女孩谈恋爱~
____toString应用____________-
公务员 [姓名:王磊, 年龄:35, 性别:男]
**********************
程序员模块:
名为冯超的程序员正在预习~
冯超正在上课中~
上课完毕,回家复习~
冯超程序员特别喜欢写代码~
冯超也喜欢修电脑Bug
冯超是位男程序员,今年24岁正在和隔壁女孩谈恋爱~
______toString应用____________
程序员 [姓名:冯超, 年龄:24, 性别:男]
***********************
学生比较模块:
________equals比较运用___________
$传入参数为null,无法比较!
$传递的不是学生对象!
$学生自己比自己,当然是同一人!
学生1与学生2是同一人
学生1与学生3不是同一人
学生1与学生4不是同一人
学生2与学生3不是同一人
学生2与学生4不是同一人
学生3与学生4不是同一人
************************
_______instanceof的应用________
——传入为空时——:
传入为空:停止
——传入为学生时——:
上课了李芳同学上课去了
李芳同学正在预习中~~
上课完毕,回家复习~~
——传入为程序员时——:
冯超程序员特别喜欢写代码~
冯超也喜欢修电脑Bug
——传入为公务员时——:
公务员王磊在无聊的开会中~
————————————作 业 完 结—————————————————
【总结完毕】
2017.12.26(西开)
以上是关于Java学习总结——面向对象(下)(接口,抽象类,内部类,String类等)的主要内容,如果未能解决你的问题,请参考以下文章
201771010125王瑜《面向对象程序设计(Java)》第八周学习总结
张季跃 201771010139《面向对象程序设计(java)》第八周学习总结