黑马程序员——Java学习之类与多态

时间:2022-02-09 15:41:45

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

类是面向对象编程中最重要的概念,类是Java程序的基本组成要素。

类声明
类声明: 类修饰符 class 类名 extends 父类名 implements 接口名 {…}

类的修饰符主要有:
•abstract(抽象类) 没有实现的方法,也没有构造方法,可以有抽象方法(只定义方法,不实现)。不能用new操作直接生成实例。不能派生之类。
•final(终结类) 不能派生子类,防止盲目继承,提供系统的安全性。保证类功能不变。
•public(公共类) 可在相同包中访问,不同包中的类都通过import引用后访问。

. 类体
{ }中是类体,包括该类的全部变量和方法。
类成员分为实例成员和类成员两种。区别:在类声明时是否用类修饰符static.(如用static修饰类class,则为类成员,否则是实例成员)。

类体格式: 修饰符 类型变量名
修饰符 返回类型 类方法名( 参数列表 ) throws 异常列表 { 方法体 }

类体中 变量 修饰符:
•public, protected, private 变量访问权限
•static 变量是类变量
•final 常量
•transient 暂时性的变量,通知虚拟机该变量不属于永久状态,用于不同对象的存档
•volatile 多个并发线程共享变量

类 方法 修饰符:
•public, protected, private 方法访问权限
•static 类方法
•final 或abstract方法是否可重写
•native 表示可将java代码与其他语言代码集成
•synchronized 表示同步操作,可用来控制并发线程,共享数据访问

构造方法
构造方法特点:
•构造方法名与类名必须相同
•构造方法是给对象赋初值,所以没有返回值,但不用void来声明
•构造方法不能被程序调用,只能通过new自动调用
•构造方法可由编程人员在类中定义,默认时由Java语言自动生成。但它是个空方法,变量
被赋予该数据类型的默认值
•构造方法可以重载实现不同的初始化方法。调用时按参数决定调用哪个方法

与类相关的多态:
多态的概念:

1.首先多态一定要在继承的前提下;
2.通常情况下,我们实例化类对象:

        class Fu{
}
class Zi extends Fu{
}
class Demo{
main(){
Zi zi = new Zi();
//多态的使用
Fu fu = new Zi();
}
}
一个父类的引用指向了它的一个子类的对象,这种情况就叫:多态;
*/
class Person
{

String name;
int age;
}
class Student extends Person
{


}
class Teacher extends Person
{

}
class Demo
{

public static void main(String[] args)
{
//多态:父类的引用指向了子类的对象
Person p = new Student();
System.out.println(p.name);

Person p2 = new Teacher();
//不可以
// Student stu = new Teacher();//编译错误,不兼容的类型;


}
}

多态访问成员的特点:

1.成员变量:编译看左边(父类,一定要有),运行时看左边(父类,子类覆盖了父类的成员变量时,打印出的就是父类的变量值)
2.成员方法:编译看左边(父类,一定要有),运行时看右边(子类,子类覆盖了父类的成员方法时,调用的是子类的方法);
3.静态方法:编译看左边(父类,一定要有), 运行时看左边(父类的)

简单说:当多态时,要访问的成员父类中必须要有,否则编译错误;
当子类覆盖父类的成员时,只有当访问是被覆盖的方法时,访问的是子类的,其它都是父类的。

class A
{

int num = 10;

void fun1(){
System.out.println("fu --> fun1()");
}
static void m(){
System.out.println("fu类的静态方法m()");
}
}
class B extends A
{

int num = 30;
int num2 = 20;
void fun1(){
System.out.println("zi 类重写-- > fun1()");
}
void fun2(){
System.out.println("zi --> fun2()");
}
static void m(){
System.out.println("zi类的静态方法m()");
}
}
class Demo
{

public static void main(String[] args)
{
A a = new B();
System.out.println(a.num);//10
// System.out.println(a.num2);//编译错误,父类中没有num2变量
a.fun1();
// a.fun2();//编译错误,父类中没有fun2()方法;

a.m();
}
}

请让我轻轻地告诉你多态是多么的方便了程序员们,让他们在后期修改之]前合作编写软件时的益处所在:
首先上个“跑图”的例子,跑图中原本有三个类:Line、Tu、Demo,原本一旦出现新增或路线更改时,我们需要的三个类都同时进行修改,造成人员劳动的重复和浪费。经过引入多态处理的新程序,我们可以发现当路线出现修改任务时,没有造成另外两个类的附带修改,减少不必要的工作量。所以下面我们看看多态的巧妙之处吧!

class MyLine
{

void show(){
}
}
class Line1
{

void show(){
System.out.println("线路1");
}
}
class Line2
{

void show(){
System.out.println("线路2");
}
}
class Line3 extends MyLine
{

void show(){
System.out.println("线路3");
}
}
class Tu
{

/*
void paoTu(Line1 line){
line.show();
}
*/

/*
void paoTu(Line2 line){
line.show();
}
*/

void paoTu(MyLine line){
line.show();
}
}
class Demo
{

public static void main(String[] args)
{
/*
Line1 line = new Line1();
*/

/*
Line2 line = new Line2();
*/

/*
MyLine line = new Line2();
*/

MyLine line = new Line3();
Tu tu = new Tu();
tu.paoTu(line);
}
}

转一个学习过程中遇见的漂亮诠释多态各方面细节的案例:儿子装爹。

class 爹{
int age = 60;
void teach(){
System.out.println("讲JavaEE");
}
}

class 儿子 extends 爹{
int age = 30;
void teach(){
System.out.println("讲C++");
}
void playGame(){
System.out.println("打英雄联盟");
}
}

//有一天来人,请老爹讲Java,把老爹请走了。
//之后又来个人找老爹讲Java,给的报酬还挺高,儿子想代替他爹去。于是,进入换上他爹的衣服,
//贴上胡子,跟那个人去讲课去了

main(){
老爹 kd = new 儿子();//多态
System.out.println("我今年:" + kd.age);//60
System.out.println("我给大家讲:" + kd.teach());//C++
// System.out.println("休息的时候自己做点自己的事,打游戏:" + kd.playGame());//不能打

//讲完之后回家,换衣服,洗脸,返回到儿子原样
儿子 kz = (儿子)kd;
kz.playGame();
}
*/
class 老爹{
int age = 60;
void teach(){
System.out.println("讲JavaEE");
}
}

class 儿子 extends 老爹{
int age = 30;
void teach(){
System.out.println("讲C++");

}
void playGame(){
System.out.println("打英雄联盟");
}
}
class Demo
{

public static void main(String[] args)
{
老爹 kd = new 儿子();//多态
System.out.println("我今年:" + kd.age);//60
System.out.println("我给大家讲:" + );
kd.teach();//C++
// System.out.println("休息的时候自己做点自己的事,打游戏:" + kd.playGame());//不能打

//讲完之后回家,换衣服,洗脸,返回到儿子原样
儿子 kz = (儿子)kd;
kz.playGame();
}
}

String类的操作:
java.lang.String类:

1.String 类代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。
2.字符串是常量;它们的值在创建之后不能更改。
3.获取一个String对象,可以通过字面常量赋值,也可以通过new关键字调用String的构造函数;
String str = “abc”;//OK的
String str2 = new String(“abc”);//OK;

4.构造函数:
1).String(): 初始化一个新创建的 String 对象,使其表示一个空字符序列。
2).String(byte[] bytes) :通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
3).String(byte[] bytes, int offset, int length):通过使用平台的默认字符集解码指定的 byte 数组,,从offset开始,取length长度;
4).String(char[] value) 分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。
5).String(char[] value, int offset, int count) 分配一个新的 String,它包含取自字符数组参数一个子数组的字符。
6).String(String original):初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。

public class StringDemo01 {

public static void main(String[] args) {
String str = "abc";//隐式的实例化对象;
str = "bbbb";
System.out.println(str);

String str1 = new String();
System.out.println("str1是不是空引用?" + (str1 == null));//false
System.out.println("字符串长度:" + str1.length());//0
System.out.println("str1开始" + str1 + "结束");

byte[] byteArray = {97,98,99,100};
String str2 = new String(byteArray);//将byte数组中的每个值作为Unicode编码,输出编码对应的字符;
System.out.println("str2的长度:" + str2.length());
System.out.println("str2 = " + str2);

//String(byte[] bytes, int offset, int length)
String str3 = new String(byteArray,0,2);
// String str3 = new String(byteArray,0,5);//java.lang.StringIndexOutOfBoundsException
System.out.println("str3 = " + str3);

//String(char[] value)
char[] charArray = {'x','y','z'};
String str4 = new String(charArray);
System.out.println("str4 = " + str4);

//String(char[] value, int offset, int count)
String str5 = new String(charArray,1,2);
System.out.println("str5 = " + str5);//yz

//String(String original)
String str6 = new String("abcd");
System.out.println("str6 = " + str6);
}

}

String的特点:

字符串是常量;它们的值在创建之后不能更改。

比较的就是两个字符串对象中存储的字符序列是否完全相同

public class StringDemo3 {

public static void main(String[] args) {
String str1 = "hello";
str1 += "world";
System.out.println("str1 = " + str1);//helloworld;

String str2 = "hello";
String str3 = "hello";
System.out.println("str2 == str3 : " + (str2 == str3));//true
System.out.println("str2.equals(str3) : " + str2.equals(str3));//true

String str4 = new String("hello");
String str5 = new String("hello");
System.out.println("str4 == str5 : " + (str4 == str5));//false
//String类重写了equals方法,否则equals方法默认是比较的两个对象的地址;
//重写后,比较的就是两个字符串对象中存储的字符序列是否完全相同;
System.out.println("str4.equals(str5) : " + str4.equals(str5));//true

String str6 = new String("hello");
String str7 = "hello";
System.out.println("str6 == str7 : " + (str6 == str7));//false
System.out.println("str6.equals(str7) : " + str6.equals(str7));//true

String str8 = "hello";
String str9 = "world";
String str10 = "helloworld";
String str11 = "hello" + "world"; //String str11 = "helloworld";
String str12 = str8 + str9;
String str13 = str8 + "world";
String str14 = "hello" + str9;

System.out.println("str10 == str11 : " + (str10 == str11));//true
System.out.println("str11 == str12 : " + (str11 == str12));//false
System.out.println("str11 == str13 : " + (str11 == str13));//false
System.out.println("str11 == str14 : " + (str11 == str14));//false
/*
byte b1 = 10;
byte b2 = 20;
byte b3 = 10 + 20;//OK的,常量相加
byte b4 = b1 + b2;//编译错误
byte b5 = b1 + 20;//编译错误
byte b6 = 10 + b2;//编译错误
*/

}
}

经常用得到的其他一些String类的操作:

替换功能
String replace(char old,char new):将字符串中的old字符替换为new字符
String replace(String old,String new)

去除字符串两空格
String trim():去除字符串两边的空格

按字典顺序比较两个字符串
int compareTo(String str)
int compareToIgnoreCase(String str)

public class Demo {
public static void main(String[] args) {
String str = "helloworld";
//String replace(char old,char new)
System.out.println("将\"helloworld\"中的l替换为L: " + str.replace('l', 'L'));
System.out.println("替换后的原字符串:" + str);
System.out.println("将:" + str + " 中的ll替换为LL: " + str.replace("ll", "LL"));
System.out.println("替换后的原字符串:" + str);
//String trim()
String loginName = "admin";
String uName = " admin ";
System.out.println("\"" + loginName + "\".equals(\""
+ uName + "\") : " + loginName.equals(uName));
System.out.println("将:\"" + uName + "\"去除两边空格:" + (uName = uName.trim()));
System.out.println("\"" + loginName + "\".equals(\""
+ uName + "\") : " + loginName.equals(uName));

//int compareTo(String str)
String str1 = "a";//97
String str2 = "b";//98
String str3 = "a";//97
String str4 = "c";//99
String str5 = "A";//65
String str6 = "ac";
String str7 = "ab";

System.out.println("\"b\".compareTo(\"a\") : " + str2.compareTo(str1));//98 - 97
System.out.println("\"a\".compareTo(\"b\") : " + str1.compareTo(str2));//97 - 98
System.out.println("\"a\".compareTo(\"a\") : " + str1.compareTo(str3));//97 - 97
System.out.println("\"c\".compareTo(\"a\") : " + str4.compareTo(str1));//99 - 97
System.out.println("\"a\".compareTo(\"c\") : " + str1.compareTo(str4));//97 - 99
System.out.println("\"a\".compareTo(\"A\") : " + str1.compareTo(str4));//97 - 65
System.out.println("\"ac\".compareTo(\"ab\") : " + str6.compareTo(str7));

//int compareToIgnoreCase(String str)
String str8 = "a";
String str9 = "A";
System.out.println("\"a\".compareToIgnoreCase(\"A\") : " + str8.compareToIgnoreCase(str9));

}

}

示例:将数组转换为字符串输出;

把数组中的数据按照指定个格式拼接成一个字符串
举例:int[] arr = {1,2,3}; 输出结果:[1, 2, 3]

public class Demo {
public static void main(String[] args) {
int[] arr = {1,2,3};
String str = "[";
for(int i = 0 ;i < arr.length ; i++){
str += arr[i];
if(i != arr.length - 1){
str += ",";
}
}
str += "]";

System.out.println(str);
}
}

CharArray:
将所输入的字符串进行反转
举例:键盘录入”abc” 输出结果:”cba”


import java.util.Scanner;

public class Demo {

public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("请输入字符串:");
String str = sc.next();
//准备一个新的字符数组,存储字符串中的字符;
char[] newCharArray = new char[str.length()];
int newCharIndex = 0;
//反向的遍历字符串
for(int i = str.length() - 1 ; i >= 0 ; i--){
char c = str.charAt(i);
newCharArray[newCharIndex++] = c;
}
//遍历之后,新数组中就是一个反转后的。将字符数组转换为字符串;
String newString = new String(newCharArray);
System.out.println("反转后的字符串为:" + newString);
}
}


——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-